Time based deceleration?

Started by
5 comments, last by BleedingBlue 17 years, 12 months ago
Well my problem is, I'm trying to keep all my movement based on a timestep, which is working great for everything but deceleration. This is what I currently have, and it works great when the time between frames is ~3-4ms.

//Where p1.deceleration = 0.99;
    p1.velocityY *= p1.deceleration;
    p1.velocityX *= p1.deceleration;

    p1.destX += p1.velocityX * FPSTimeAv;
    p1.destY += p1.velocityY * FPSTimeAv;

//Velocity increase.
//FPSTimeAv is the average time across 50 frames

        p1.velocityX -= (sin(p1.angle * 0.0174532925)) * p1.acceleration;
        p1.velocityY += (cos(p1.angle * 0.0174532925)) * p1.acceleration;

However whenever I force the frametime up it obviously decelerates less per second, and so the ship coasts further and further as the Frametime goes up.

//Where p1.deceleration = 0.99 * ~4

    p1.velocityX *= p1.deceleration / FPSTimeAv;
    p1.velocityY *= p1.deceleration / FPSTimeAv;

    p1.destX += p1.velocityX * FPSTimeAv;
    p1.destY += p1.velocityY * FPSTimeAv;

//Velocity increase.
//FPSTimeAv is the average time across 50 frames

        p1.velocityX -= (sin(p1.angle * 0.0174532925)) * p1.acceleration;
        p1.velocityY += (cos(p1.angle * 0.0174532925)) * p1.acceleration;


The problem I run into is if I add a FrameTime modifier then two things happen the first, is deceleration is very very sporadic, sometimes it will slow down within about 64 pixels, other times about 2. The second is, if FPSTimeAv plummits then the modified deceleration actually increases velocity (due to it becoming greater then 0.99). My question is, how would I add deceleration without having it become sporadic, and unpredictable?
Advertisement
I do something like velocity -= deceleration * delta where deceleration is the number of units/sec that the ship should slow, instead of a multiplier. If you're using time-based movement, it helps to define all your metrics in units/sec (degrees/sec for rotation, feet/sec for movement, etc) instead of some abstract "this should make it slow down in the right amount of time" value.
If I read this correctly, you're using a multiplier to achieve an effect like losing 1/3 of your speed every second.

In that case, use:
    p1.velocityX *= pow(p1.deceleration,-dt);    p1.velocityY *= pow(p1.deceleration,-dt);


where p1.deceleration is the fraction of the velocity remaining after one second, and where dt is the number of seconds since the last update, not averaged.

This formula is equivalent to the exponential decay formula
final = initial * e^(-ln(deceleration) * dt).
Here is an example of your problem. Say the initial velocity is 1 and in one case the frame rate is 10 fps and in another case the frame rate is 100 fps. Here are the velocities using your v' = v * 0.99 formula:
    Time     10 fps  100 fps    ------   ------  -------      0 ms   1.0000  1.0000     10 ms           0.9900     20 ms           0.9801     30 ms           0.9703     40 ms           0.9606     50 ms           0.9510     60 ms           0.9415     70 ms           0.9321     80 ms           0.9227     90 ms           0.9315    100 ms   0.9900  0.9044    ...    200 ms   0.9801  0.8179 
See what's happening?

Both of the suggestions that Guru2012 and jonahrowley make are correct, but the results are different. You need to decide which one is closer to what you are trying to achieve.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Well I tried this

p1.velocityX *= pow(p1.deceleration,-dt);
p1.velocityY *= pow(p1.deceleration,-dt);

and I still get a disparity depending on the frame rate. I've even looked at exponential decay formula's and tried then, and still I get a huge difference.

Have you been using the time difference between frame rates for dt instead of the average time difference?
Yes, using 0.99 and the non averaged time delta with 2 tests, one with a simulated delay of 8 ms between frames, and one with a simulated delay of 60 ms between frames, the 8ms one starts with a y velocity of 1 at 0 px, and travels to about 241 px, and the 60ms one with all the same starting conditions except for 60ms between frames travels to about 188px.

This topic is closed to new replies.

Advertisement