SFML community forums

Help => General => Topic started by: fatum on January 31, 2012, 11:12:44 am

Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: fatum on January 31, 2012, 11:12:44 am
Currently I'm trying something like this:

Code: [Select]

const int gameTime = 10;
sf::Clock gameClock;

...

while (gameClock.GetElapsedTime().AsMilliseconds() > gameTime)
{
     gameClock.Restart();
     //update game
}


This doesn't quite work the same way as it did previously with GetFrameTime() in replace of the sf::Clock.  I'm having quite a bit of difficulty syncing up everything again after I updated to the newest SFML 2 build.

Would there be a better method for handling a fixed time step?

Thanks for any help!
Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: Mario on January 31, 2012, 12:24:40 pm
You always have to preserve additional time that has been passed. My game right now runs at 100 updates per second and with the new Time stuff in SFML2 it runs very smooth at a constant rate of 100 updates per second:
Code: [Select]
sf::Timer timer;
double skippedTime = 0;
while (running) {
  const double elapsedTime = timer.Restart().AsMicroseconds() / 1000.;
  skippedTime += elapsedTime;

  while (skippedTime > 10) {
    // event handling
    // updating
    skippedTime -= 10;
  }
  // drawing
}


Please note that this code might get "stuck" if your framerate is far too low to catch up, so you might want to limit skippedTime some way, e.g. by limiting the number of iterations per frame to 10 and then dropping any iterations unhandled (e.g. calling "skippedTime %= 10").
Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: BlueMagic on January 31, 2012, 04:25:36 pm
Why not make the movement frame independent?
Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: Mario on January 31, 2012, 06:40:40 pm
It already is frame rate independent (there can be x updates between two frames being drawn).

The simple reason for this is (at least for me): It makes updating and simulation a lot easier to do. E.g. instead of moving some entity by "speed * deltaTime" and then testing every x units to see if it collides, you just move it by"speed" every iteration. In the end it's essentially the same approach, but you're forcing a fixed number of updates per second, which can be a lot more beneficial, especially if you're trying to do networking and/or some kind of demo recording.
Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: model76 on January 31, 2012, 07:31:00 pm
Quote from: "BlueMagic"
Why not make the movement frame independent?
This can be bad if you use a physics simulation, and is one place where you can see the chaos theory in action. Tiny little differences caused by rounding inaccuracies may cause the simulation to "explode".

The consensus seem to be that fixed frame rate, or fixed time step with independent frame rate, is the way to go.

Personally, I have found the "position += velocity / frameTime" method a great learning step, though.

My favorite article on game loops: http://www.koonsolo.com/news/dewitters-gameloop/

Unless I misunderstood your suggestion, of course.  :wink:
Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: fatum on February 01, 2012, 04:44:09 am
Quote from: "Mario"
You always have to preserve additional time that has been passed. My game right now runs at 100 updates per second and with the new Time stuff in SFML2 it runs very smooth at a constant rate of 100 updates per second.


Thanks for the help!  However, I'm still having trouble getting everything at the same speed it was whenever I was using RenderWindow.GetFrameTime(); in my fixed time step.  Currently everything moves a lot faster than it did before.

What was GetFrameTime() doing?  Initially I thought it returned the difference in time between the current tick and the previous tick, but I'm not entirely sure if that's true.
Title: Fixed time step (now that GetFrameTime() has been removed)
Post by: Mario on February 04, 2012, 04:06:16 pm
It returned the time passed while rendering the last frame (I'm not 100% sure if that's Display() to Display() or Clear() to Display() though.

In my code example above the time returned by the timer is always the time that passed during/while the last iteration/tick, but the updates run once every 10 ms (so that would be the "last frame time" here).