Advertisement

Newton's laws help

Started by December 12, 2015 09:13 AM
12 comments, last by Scottehy 9 years, 2 months ago

I noticed the divide by zero was happening when the screen would go fully black. Thus the normalizing causing the issue, due to retro being zero. How exactly does the above cause the rocket to be more responsive though? Unless I'm implementing your math wrong. I find when I begin to turn I lose most of my velocity exceptionally quick. But that was with a retroforce of 5 etc, where as 1 feels a lot nicer, except I'm still drifting a lot like before. Either the values I'm using are way off, or I'm not implementing it correctly to be able to do a smooth 180 turn etc, and still keep majority of my velocity.


float rocket_boost = 0.0f;
if (Global.Instance.IsDown(Keys.W))
    rocket_boost = 2000.0f;
Vector2 force = direction * rocket_boost;
mass = 10.0f;
Vector2 acceleration = force / mass;
velocity += acceleration * DT;

Vector2 desired = direction * velocity.Length();
float retroForce = 5.0f;
Vector2 retro = desired - velocity;
retro.Normalize();
float retroLength = retro.LengthSquared();
if (retroLength > 0)
{
    retro /= (float)Math.Sqrt(retroLength);
    retro *= retroForce;
    velocity += retro;
}

position += velocity * DT;

Thanks so much for the help you're providing though. I can't believe how much more there is to moving objects than I've previously done. When ever I've implemented movement before, it has been nothing remotely detailed in comparison.

The retroForce value is there to allow you to tweak the sensitivity a bit but as you notice it will still drift. If you really don't want any drift you will have to cheat at which point it's no longer Newtonian.

Newton's first law:

When viewed in an inertial reference frame, an object either remains at rest or continues to move at a constant velocity, unless acted upon by an external force

Which is the exact issue you have, unless you apply a force to stop the current velocity then it will remain. Once you have turned 180 degrees then your ship's main thruster is working to counter the initial velocity. Another method to deal with this is to add some drag (air resistance) https://en.wikipedia.org/wiki/Drag_%28physics%29

I've simplified this from the equation given on the wiki page


speed = velocity.squaredLength(); // we need speed so we might as well calculate and normalize using it
if(speed > 0)
{
   frictionForce = -velocity; // friction works in the opposite direction
   frictionForce /= speed; // friction is just a direction now as it's been normalized
   // drag multiplier is just a number you can tweek, I don't know what a good value would be
   frictionForce *= dragMultiplier*speed*speed;
   velocity += frictionForce/mass;
}

That will cause your ship to always slow down when you are not applying thrust. There is no drag in space but for a game it might work well. It will also prevent your ship reaching undesirably high speeds.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

Advertisement

Make it an additional stabilizing control component for your ship that the player can add in the game. It would apply small counter thrust force to "stabilize" the ship, ie slowly reduce its speed to 0 in all directions if the player doesn't engage a thruster.

Make it an additional stabilizing control component for your ship that the player can add in the game. It would apply small counter thrust force to "stabilize" the ship, ie slowly reduce its speed to 0 in all directions if the player doesn't engage a thruster.


I was thinking of doing this, but wondering the best way to do it. Possibly lerp the velocity vector to vector.zero if the player isn't accelerating. Or should i just be applying counter thrust in the opposite direction the player is traveling? Both would probably end up doing the same, but i imagine lerping might be smoother. I'd test it now but im at work heh.

This topic is closed to new replies.

Advertisement