开发者

Correct movement in asteroids type game

At the moment I have some sort of asteroids game, which can been seen here:

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

But at the moment when the user presses W when the ship is still moving, it will take the speed the ship is moving in regardless of its rotation and add to it, causing the ship to appear jerky and not coordinated (hard to explain, watch the video).

Here is the code I'm using:

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
   开发者_JAVA技巧 {
        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;

        }
    }

Is there anyway I can accomplish this without introducing a dx and dy values? With a minimum modification as possible?


The problem is obvious, even though you are facing a direction, it doesn't mean that you would move in that direction when you turn on your thrusters.

You need a second, internal direction vector that gets updated when your thrusters are on, most likely through a simple vector addition and a subsequent normalization. You then use that direction to calculate the direction you apply the force to the ship.


In the end, I used this:

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;


Keep track of the player's motion in terms of a dx and dy, rather than a speed and angle, and add to those values when W is pressed.


I think the problem is that you're adding the impulse from pressing W directly to the X,Y co-ordinates. What you need to do is have a velocity vector with X, Y co-ordinates, and add to that when the user thrusts.

The on each time step you add the x-velocity and y-velocity components to the X,Y co-ordinates.

The underlying physics is that you have position (x,y), velocity (dx/dt, dy/dt) and acceleration (dx^2/dt, dy^2/dt). Thrust provides an acceleration that you have to integrate over time to provide velocity, which is then integrated over time to give position.


There are two "concepts" from physics which you need to implement: Speed and friction.

Here is a simple example in 2D. You may also use wrapper classes to combine the x/y variables into a single object and provide handy methods to alter their content.

Each object needs to have a position and a speed variable. We also need friction, which is a constant for each material (as your object probably always travels in the same material, we will just model friction to be constant). 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;
    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;
    }
}

Notice that your object has an update method. this method needs to be called on all objects in your scene regularly, to apply the movement. In this method you could also process collision detection and enemies could do their AI logic..

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜