1
\$\begingroup\$

Slowing down a character using the following formula returns different results depending on the frame rate:

this.y += this.yVel * delta;
this.yVel *= Math.pow(0.99, delta);

Is there a better way to decelerate a player using delta time to allow for consistent movement across several framerates?

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

Normally, fixed delta time is used in physics simulation cause in this reason. On the other hand, frame base delta time is useful for rendering.

Of course, fixed delta base calculation result is make diff frame time object position. So you will need interpolation.

\$\endgroup\$
0
\$\begingroup\$

This line assumes that yVel is constant for the entirety of the duration delta:

this.y += this.yVel * delta;

But that's not true - we know by the end of duration delta that yVel has decreased to a fraction of \$0.99^\text{delta}\$ according to this line:

this.yVel *= Math.pow(0.99, delta);

So if we think of yVel as a function of time, \$v(t) = v_0 \cdot 0.99^t\$, then the total displacement in y over the course of the interval delta is the integral:

$$\begin{align} \Delta y &= \int_0^\text{delta}v_0 \cdot 0.99^t dt\\ &= v_0 \cdot \int_0^\text{delta} e^{\ln (0.99) \cdot t} dt\\ &= v_0 \cdot \left( \frac 1 {\ln(0.99)} e^{\ln(0.99) \cdot t}\right)\Bigg|^\text{delta}_0\\ &= \frac {v_0} {\ln(0.99)}\left(e^{\ln(0.99)\cdot \text{delta}} - 1 \right)\\ &=v_0 \cdot \frac {0.99^\text{delta} - 1} {\ln(0.99)} \end{align}$$

In code:

var frictionFactor = Math.Pow(0.99, delta);
this.y += this.yVel * (frictionFactor - 1)/Math.Log(0.99);
this.yVel *= frictionFactor;

This will be smoother, but can still vary from one run to another due to limited precision and accumulation of rounding errors. So as Shin Dongho mentioned, your best bet here is to fix your physics timestep at a known value, so you get consistent, reproducible results.

\$\endgroup\$
2
  • \$\begingroup\$ I notice a recent down-vote four years after posting this. If there's some error or problem in this answer, I'd be happy to make improvements. (Mostly I don't want to Community user bot to bump this thread forever since it has only 0-point answers) \$\endgroup\$
    – DMGregory
    Commented Nov 22, 2023 at 12:14
  • \$\begingroup\$ Still bumping(I did not do it, but I know why). Your answer has the proper math, but still misses the point. Accumulate and distribute the error. Hint: Think of moving an object at an integer speed slower than one. Provide another answer, since this one is good and mostly relevant, and I will upvote it. \$\endgroup\$
    – agone
    Commented Sep 18 at 0:01

You must log in to answer this question.