Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Fixed time step (now that GetFrameTime() has been removed)  (Read 8607 times)

0 Members and 1 Guest are viewing this topic.

fatum

  • Newbie
  • *
  • Posts: 47
    • MSN Messenger - bowsers7@hotmail.com
    • AOL Instant Messenger - therealblah569
    • View Profile
    • http://boards.psynetfm.com
Fixed time step (now that GetFrameTime() has been removed)
« 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!

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Fixed time step (now that GetFrameTime() has been removed)
« Reply #1 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").

BlueMagic

  • Newbie
  • *
  • Posts: 49
    • View Profile
Fixed time step (now that GetFrameTime() has been removed)
« Reply #2 on: January 31, 2012, 04:25:36 pm »
Why not make the movement frame independent?

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Fixed time step (now that GetFrameTime() has been removed)
« Reply #3 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.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Fixed time step (now that GetFrameTime() has been removed)
« Reply #4 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:

fatum

  • Newbie
  • *
  • Posts: 47
    • MSN Messenger - bowsers7@hotmail.com
    • AOL Instant Messenger - therealblah569
    • View Profile
    • http://boards.psynetfm.com
Fixed time step (now that GetFrameTime() has been removed)
« Reply #5 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.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Fixed time step (now that GetFrameTime() has been removed)
« Reply #6 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).