且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我应该如何在这个 2d Java 游戏中实现跳跃/重力/坠落

更新时间:2022-11-10 09:29:59

你想做的,是实现速度加速度重力> 用于场景中的对象.速度是一个二维向量,它告诉您物体移动的速度,而加速度则告诉您速度增加了多少.

What you want to do, is implement speed, acceleration and gravity for the objects on your scene. Speed is a 2D vector, which tells you how fast something moves, while acceleration tells you how much the speed increases.

所有对象都应该有一个 update() 方法,该方法会定期调用.它会将物体的速度应用到它的位置(这就是速度和位置之间的关系),当你想加速一个物体时,你基本上只会增加它的速度.在 update() 方法中,我们还应用了重力(以负 Y 加速度的形式)

All objects should have an update() method, which is called periodically. It will apply the speed of the object to it's position (that's how speed and position are related anyways) and when you want to accelerate an object, you will basically just increase its speed. In the update() method we also apply gravity (in form of negative Y acceleration)

你也可以利用摩擦.摩擦力确保您的物体在向某个方向移动时会减速.

You can also make use of friction. Friction makes sure that your objects will slow down, as they move into a certain direction.

在这个简单的模拟中,摩擦变弱,因为值接近 1.这意味着在 FRICTION==1 你没有摩擦,在 FRICTION==0 你的物体会立即停止.

In this simple simulation, friction gets weaker, as the value approaches 1. That means at FRICTION==1 you have no friction and at FRICTION==0 your objects will stop immediately.

public class PhysicsObject {
    public static final double FRICTION = 0.99;
    public static final double GRAVITY = 0.01;
    private double posX;
    private double posY;
    private double speedX = 0;
    private double speedY = 0;

    public PhysicsObject(double posX, double posY) {
        this.posX = posX;
        this.posY = posY;
    }

    public void accelerate(double accelerationX, double accelerationY) {
        speedX += accelerationX;
        speedY += accelerationY;
    }

    public void move(double xDelta, double yDelta) {
        posX += xDelta;
        posY += yDelta;
        // do collision detection here. upon collision, set speedX/speedY to zero..!
    }

    public void update() {
        move(speedX, speedY);
        speedX *= FRICTION;
        speedY *= FRICTION;
        accelerate(0, -GRAVITY); // gravity accelerates the object downwards each tick
    }

    public double getPosX() {
        return posX;
    }

    public double getPosY() {
        return posY;
    }
}

您还可以使用 update() 来处理碰撞检测(应该将速度设置为零)并且敌人可以执行他们的 AI 逻辑..

You can also use update() to process collision detection (which should set speed to zero) and enemies could do their AI logic..

你类 Player 可以扩展这个 PhysicsObject 并拥有方法 jump()runLeft()runRight(),可能看起来像这样:

You class Player could extend this PhysicsObject and have the methods jump(), runLeft() and runRight(), which could look like this:

public class Player extends PhysicsObject{
    public static final double JUMP_STRENGTH = 5;
    public static final double SPEED = 1;
    public void jump() {
        accelerate(0, JUMP_STRENGTH); // change 5 for some constant or variable indicating the "strength" of the jump
    }

    public void runRight() {
        move(SPEED, 0);
    }

    public void runLeft() {
        move(-SPEED, 0);
    }
}

碰撞检测本身就是一件大事,在这里介绍太多了,但是 这个视频很好地描述了它.去看看!

Collision detection is a huge thing on it's own and it would be too much to cover here, but this video describes it very well. Go check it out!