Advertisement

Jumping The Same Height At All FPS

Started by March 28, 2018 09:15 PM
4 comments, last by GameCreator 6 years, 8 months ago

This should be something really simple but I can't wrap my head around it.  I'm using an engine with Time::GetSpeed() function.  It returns a float based on what fraction of 60fps the game is running at.  So it returns 1.0 at 60fps, 2.0 at 30fps, 4.0 at 15fps, 60.0 at 1fps, etc.  That means you can use the function to adjust movement to compensate for different fps.

I tried to use it to write a simple jump code but it doesn't work and I'm not sure why.  Here are the relevant lines:


if(window->KeyHit(Key::Space)) vy=0.8;  //  Jump if Space is hit

...

vy-=0.05*Time::GetSpeed();  //  Add gravity every frame

y+=vy*Time::GetSpeed();  //  Add velocity to y every frame

...
  
Sleep(1);

I then increase the Sleep function parameter to slow the game down.  The problem is that the lower the fps gets, the lower the jump becomes.  I also tried removing *Time::GetSpeed from the gravity line (seems like it's redundant) but then the character jumps really high when the fps gets low.

What am I doing wrong?

Nothing, except perhaps integrating linearally.  See also Riemann_sum integration.  Using a shorter dt gives a more accurate total distance traveled in the jump compared to a longer dt.

The “de facto” solution is Fix Your Timestep, where the simulation is integrated in fixed steps, and the state is tweened in between updates while rendering.

Advertisement

That ^^, but to put it in other words, this method of adding acceleration to velocity and velocity to position is a way of solving an integration problem - you're doing calculus. 

This method of slicing up small bits of time and adding the derivative deltas on is often called Newton's method, but it's only stable if you use fixed size slices. It can also be quite approximate depending on your slice size. As mentioned above, there are many other types of integrators that you could use instead, or alternatively you can use that method of running your gameplay code with a fixed timestep.

Some more wiki links on the topic :) :

https://en.m.wikipedia.org/wiki/Numerical_integration

https://en.m.wikipedia.org/wiki/Newton–Cotes_formulas

https://en.m.wikipedia.org/wiki/Runge–Kutta_methods#The_Runge–Kutta_method

I managed it just fine with the xacceleration and yacceleration attributes of objects in the SGE Game Engine. I followed the suggestion of a coworker at the time and used the kinematic equations.

Source code is here if you want to see the specifics:

https://savannah.nongnu.org/git/?group=stellarengine

Thank you guys.  I saw that Fix Your Timestep page a long time ago and this is a good time to revisit and implement one of the suggested options.

This topic is closed to new replies.

Advertisement