Stathis Posted January 22, 2017 Share Posted January 22, 2017 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. 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. Link to comment Share on other sites More sharing options...
samme Posted January 23, 2017 Share Posted January 23, 2017 Try removing drag. drhayes 1 Link to comment Share on other sites More sharing options...
Stathis Posted January 24, 2017 Author Share Posted January 24, 2017 @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. Link to comment Share on other sites More sharing options...
samme Posted January 25, 2017 Share Posted January 25, 2017 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() ); drhayes 1 Link to comment Share on other sites More sharing options...
Stathis Posted January 25, 2017 Author Share Posted January 25, 2017 @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: 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: And it will keep going sideways, as I keep thrust pressed. (accelerationFromRotation has exactly the same effect as my acceleration calculations above) Link to comment Share on other sites More sharing options...
Stathis Posted January 27, 2017 Author Share Posted January 27, 2017 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. Link to comment Share on other sites More sharing options...
Stathis Posted January 27, 2017 Author Share Posted January 27, 2017 Ok, I have found what the problem is ! 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. Link to comment Share on other sites More sharing options...
Stathis Posted January 28, 2017 Author Share Posted January 28, 2017 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. Link to comment Share on other sites More sharing options...
Recommended Posts