在小行星类型游戏中正确运动

时间:2011-09-07 18:23:30

标签: java

目前我有一些小行星游戏,可以在这里看到:

http://www.youtube.com/watch?v=rQV6H9kWkFE

但是当用户在船仍在移动时按下W时,它将采用船舶移动的速度而不管其旋转并加到它上面,导致船只出现生涩而不协调(难以解释,观看视频)。

以下是我正在使用的代码:

public void update(int delta) throws SlickException
{
    float hip = speed * delta;

    float rotation = image.getRotation();

    for (Bullet b : bulletList)
    {
        b.update(delta);
    }

    Input input = gc.getInput();

    if (input.isKeyDown(Input.KEY_A))
    {
        image.rotate(rotateLeftSpeed * delta);

        if (rotateLeftSpeed > (ROTATE_LIMIT * -1))
        {
            rotateLeftSpeed -= rotateSpeed;
        }
    } else
    {
        if (rotateLeftSpeed < 0)
        {
            image.rotate(rotateLeftSpeed * delta);

            rotateLeftSpeed += rotateSpeed;

        }
    }

    if (input.isKeyDown(Input.KEY_D))
    {
        image.rotate(rotateRightSpeed * delta);
        if (rotateRightSpeed < (ROTATE_LIMIT))
        {
            rotateRightSpeed += rotateSpeed;
        }
    }

    else

    {
        if (rotateRightSpeed > 0)
        {
            image.rotate(rotateRightSpeed * delta);

            rotateRightSpeed -= rotateSpeed;

        }
    }

    if (input.isKeyDown(Input.KEY_W))
    {
        hip = speed * delta;
        protation = image.getRotation();
        rotation = image.getRotation();


        x += hip * Math.sin(Math.toRadians(rotation));
        y -= hip * Math.cos(Math.toRadians(rotation));
        if (speed < SPEED_LIMIT)
            speed += 0.005f;
    } else
    {
        if (speed > 0)
        {

            System.out.println(offSpeed);
            srotation = image.getRotation();
            hip = speed * delta;
            x += hip * Math.sin(Math.toRadians(protation));
            y -= hip * Math.cos(Math.toRadians(protation));
            speed -= 0.003f;

        }
    }

无论如何我可以在不引入dx和dy值的情况下完成此操作吗?尽可能少的修改?

5 个答案:

答案 0 :(得分:3)

问题很明显,即使你面向一个方向,但这并不意味着当你打开推进器时,你会向这个方向移动

你需要第二个内部方向向量,当你的推进器开启时,它会更新,最有可能是通过简单的向量加法和随后的标准化。然后使用那个方向来计算将力施加到船上的方向。

答案 1 :(得分:1)

最后,我使用了这个:

if (input.isKeyDown(Input.KEY_W))
    {

        dx += Math.sin(Math.toRadians(image.getRotation())) * delta * 0.01;
        dy += -Math.cos(Math.toRadians(image.getRotation())) * delta * 0.01;

    } 

    x += dx;
    y += dy;

    dx *= 0.98;
    dy *= 0.98;

答案 2 :(得分:0)

根据dxdy而不是速度和角度跟踪玩家的动作,并在按下W时添加到这些值。

答案 3 :(得分:0)

我认为问题在于你正在加入从W直接按X,Y坐标的冲动。你需要做的是有一个带X,Y坐标的速度矢量,并在用户推力时加上它。

在每个时间步上,将x速度和y速度分量添加到X,Y坐标。

基础物理学是你有位置(x,y),速度(dx / dt,dy / dt)和加速度(dx ^ 2 / dt,dy ^ 2 / dt)。推力提供了一个加速度,你必须随着时间的推移积分,以提供速度,然后随着时间的推移积分速度,以提供位置。

答案 4 :(得分:0)

您需要实现物理学中的两个“概念”: 速度和摩擦力。

这是2D中的一个简单示例。您还可以使用包装类将x / y变量组合到单个对象中,并提供方便的方法来更改其内容。

每个对象都需要有一个位置和一个速度变量。我们还需要摩擦,这是每种材料的常数(因为你的物体可能总是在相同的材料中运行,我们只是模拟摩擦力是恒定的)。在这个简单的模拟中,当摩擦力达到1时,摩擦力会变弱。这意味着在摩擦力= 1时你没有摩擦力,在摩擦力为0时你的物体会立即停止:

public class PhysicsObject{
    public static final double FRICTION = 0.99;
    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 update(){
        posX += speedX;
        posY += speedY;
        speedX *= FRICTION;
        speedY *= FRICTION;
    }
    public double getPosX(){
        return posX;
    }
    public double getPosY(){
        return posY;
    }
}

请注意,您的对象有一个更新方法。需要定期在场景中的所有对象上调用此方法,以应用移动。在这种方法中你也可以处理碰撞检测,敌人可以做他们的AI逻辑。