Stathis

Angular acceleration-based movement is inconsistent

Recommended Posts

Hi all. I am trying to make a simple top-down, asteroids-like game, where movement is done through Phaser's arcade physics system. I find quite puzzling how angular movement works for it. I've followed a few tutorials, where I find the same issue. What is happening is, when my ship has an angle, thrusting or reversing is quite inconsistent. The ship appears to be "slipping" a bit in random directions, and does not always follow exactly the direction it's facing.

ship_movement.gif

The relevant create code is:

player.body.maxVelocity.setTo(MAX_SPEED, MAX_SPEED);
player.body.drag.setTo(DRAG, DRAG);

whereas the relevant update code is:

if (cursors.left.isDown) {
    player.body.angularVelocity = -ROTATION_SPEED;
} else if (cursors.right.isDown) {
    player.body.angularVelocity = ROTATION_SPEED;
} else {
    player.body.angularVelocity = 0;
}
    
if (cursors.up.isDown) {
    player.body.acceleration.x = Math.cos(player.rotation) * ACCELERATION;
    player.body.acceleration.y = Math.sin(player.rotation) * ACCELERATION;
} else if (cursors.down.isDown) {
    player.body.acceleration.x = -Math.cos(player.rotation) * ACCELERATION;
    player.body.acceleration.y = -Math.sin(player.rotation) * ACCELERATION;
} else {
    player.body.acceleration.setTo(0, 0);
}

I don't understand what could be causing this. Is the code just wrong (although I've seen this happening in all the tutorials)? Is it some rounding error? Am I just being crazy seeing this as wrong behavior? Is there any way to achieve the effect I am looking for (moving diagonally back and forth, on a straight line)?

You can play around with this here as well.

Share this post


Link to post
Share on other sites

@samme thanks, this does remove the effect I mentioned! Although I liked the drag feature... Any idea why it does that?

The actual kind of movement I am going for, is the following. When the ship thrusts with an angle, the ship starts moving towards that direction. If you tilt the direction a bit (but always keep pressing thrust), the ship should keep the momentum it had for a bit, but gradually keep moving exclusively to the new direction. I know that when thrust button is not pressed, I can keep multiplying the velocity with a constant, eg 0.9, but that will only work for that case, when thrust is not pressed. Any ideas on how to do this? Do I somehow need to maintain two vectors, one for the direction, and one for the momentum, and somehow keep decreasing the momentum one? I hope all that made sense.

Share this post


Link to post
Share on other sites

Arcade Physics drag is applied separately to the X and Y axes. For spaceships that tends to bend the velocity vector toward the perpendiculars.

See accelerationFromRotation() in v2/arcade-physics/asteroids-movement.

For more "natural" drag you could try

ship.body.velocity.multiply(0.99, 0.99);

// or

ship.body.velocity.setMagnitude( -10 + ship.body.velocity.getMagnitude() );

 

Share this post


Link to post
Share on other sites

@sammethanks for the reply. But doesn't this have exactly the same problem? If I understand this correctly, body.velocity is a vector of the direction and magnitude of ship's velocity. Decreasing this on both axes, is not going to decrease the momentum (on the ship's relative x axis), it is just going to decrease the ship's current velocity. Sorry, I am not making myself very clear. I just created this image, to try to explain better:

Untitled.jpg

Imagine that this depicts the ship in different phases in time. And the arrow shows when the key is pressed. Let's say that when it starts, on the left, it has already some momentum (drag), that makes it move to the right, with no key pressed. Then up is pressed. The effect I am going for, is gradually remove the previous momentum on the x axis, and only move upwards. I think that if I do what you said, and after actually testing it, the ship will do this:

Untitled.jpg

And it will keep going sideways, as I keep thrust pressed.

(accelerationFromRotation has exactly the same effect as my acceleration calculations above)

Share this post


Link to post
Share on other sites

Ok, I believe I have found an approach to this. I think what I need is apply sideways friction when thrust is pressed. I've found this solution, adapted it to my code, and I am not sure how it does what id does , but seems to work for me! (I will probably also disable drag, as discussed above).

My ship still appears to be "slipping" a bit, on narrow angles, as described in my first post. I think this has to do with a separate issue; I will need to investigate a bit more.

Share this post


Link to post
Share on other sites

Ok, I have found what the problem is :D! There are actually two issues. One is the drag, that is mentioned above. This affects small velocities.

The other one, affects max velocities. When the ship reaches max velocity, the velocity vector is calculated wrong in Phaser. Or maybe not necessarily wrong, but different to what my expectation was. Without looking at Phaser's code, I assume it does not take into account the angle of the sprite; maybe it just checks each axis separately, and not the combined velocity vector they compose. The solution written here works perfectly for me. This also means that now my ship has steady actual max velocity, and does not run faster/slower in certain angles.

Share this post


Link to post
Share on other sites

Update: I think for the max velocity issue, it's much easier if I just do:

ship.body.velocity.setMagnitude(Math.min(MAX_SPEED, ship.velocity.getMagnitude()));

as this seems to take into account the angle. The source code actually first normalises the velocity vector and then multiplies.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.