Jump to content
  • Advertisement
Sign in to follow this  
SYJourney

Consistent physics at different framerates

This topic is 1074 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone at gamedev.net,

for a 2d game, I want the user's to be able to change the framerate in their settings (framerate won't change during gameplay tough). However I'm having trouble getting the physics consistent at different framerates. Here is what my main loop looks like:

 

update()

draw()

remaining = dpf - elapsed

if (remaining > 0)

   Sleep(remaining)

 

The value called "dpf" is the game time that should elapse in one frame. So for 60 fps, it  is 1000 / 60 = 16.

 

Now I drew this out on paper and this is what I think should do the job for physics:

 

dpfmult = dpf / 16

 

hacc = hforce / mass

vacc = vforce / mass

 

hspeed = hforce * dpfmult

vspeed = vforce * dpfmult

 

xpos += siqnsqrt(hspeed * dpfmult)

ypos += siqnsqrt(vspeed * dpfmult)

 

The reasoning being that I apply the multiplier twice, hence I take the (signed) square root at the end. Yet this gives me completely different behaviour for 120, 60 or 30 fps.

I also have animations in my game dependent on the dpf valule and those look the same at every fps. So If anyone could take a look at it and check what's wrong that would be great. Thanks!

Edited by SYJourney

Share this post


Link to post
Share on other sites
Advertisement

Thanks for the reply. The article seems to be about variable timesteps tough, I just want to enable a few different settings, 120-60-30 fps.


Read through that article in some more detail. What it is suggesting is that you control you physics update and redraws separately. If your framerate drops, you may have multiple physics and logic updates in a single redraw making sure the game continues to update in realtime. If your framerate is high enough, you may render multiple frames per physics update. If that ever happens it is key that your frame interpolation works well, otherwise you would just be rerendering the same consecutive frame. Edited by HappyCoder

Share this post


Link to post
Share on other sites

The article seems to be about variable timesteps tough


No, the article concludes that it is best to run physics with a CONSTANT timestep,
and to sync with realtime, you need to run a VARIABLE number of physics iterations per frame.

Example using 1/60 sec timestep fpr physics:
60 fps: 1 x physics per frame
30 fps: 2 x physics per frame
120 fps: run physics onle each 2nd. frame

That means graphics and physics may become out of sync,
then you need to either interpolate actual and old physics positions,
or extrapolate actual physics position with velocity to make it look smooth.
(only for nice graphics - you can care for this later)


But more inportant, your integration seems somehow wrong (or at least misleading / confusing to me).
It should be like:

float accV = -9.81f + body.forceV / body.mass; // example with gravity
body.velocityV += accV * timestep;
body.positionV += body.velocityV * timestep;

EDIT:
If you find Euler integration not 100 percent intuitive, read this about verlet integration:
http://www.pagines.ma1.upc.edu/~susin/files/AdvancedCharacterPhysics.pdf
To me that's much easier, and also it's very stable. Edited by JoeJ

Share this post


Link to post
Share on other sites

Okay so if I follow the above it would look like this?

 

elapsed = last - now

while (elapsed > 0)

   update(16)

   elapsed -= 16

draw(elapsed) // use remainder to extrapolate

 

Just in theory, not accurately I mean.

Edited by SYJourney

Share this post


Link to post
Share on other sites

Almost. (Changes bold)

 

Okay so if I follow the above it would look like this?

 

elapsed = last - now

while (elapsed > 16)

   update(16)

   elapsed -= 16

draw(elapsed) // use remainder to extrapolate

 

Just in theory, not accurately I mean.

Share this post


Link to post
Share on other sites

I've tested it a bit more, one more question tough, shouldn't I keep the remaining time between cycles too?

 

remain += last - now

while (remain > 15)

   update(16)

   remain -= 16

draw (remain)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!