Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In Gaffer's "Fix Your Timestep!" article, the author explains how to free your physics' loop from the paint one.

Here is the final code, written in C:

double t = 0.0;
const double dt = 0.01;

double currentTime = hires_time_in_seconds();
double accumulator = 0.0;

State previous;
State current;

while ( !quit )
{
     double newTime = time();
     double frameTime = newTime - currentTime;
     if ( frameTime > 0.25 )
          frameTime = 0.25;   // note: max frame time to avoid spiral of death
     currentTime = newTime;

     accumulator += frameTime;

     while ( accumulator >= dt )
     {
          previousState = currentState;
          integrate( currentState, t, dt );
          t += dt;
          accumulator -= dt;
     }

     const double alpha = accumulator / dt;

     State state = currentState*alpha + previousState * ( 1.0 - alpha );

     render( state );
}

I'm trying to implement this in JavaScript but I'm quite confused about the second while loop...

Here is what I have for now (simplified):

...
(function animLoop(){
  ...

  while (accumulator >= dt) { // While? In a requestAnimation loop? Maybe if?
    ...
  }

  ...
  // render

  requestAnimationFrame(animLoop); // stand for the 1st while loop [OK]
}())

As you can see, I'm not sure about the while loop inside the requestAnimation one...

I thought replacing it with a if but I'm not sure it will be equivalent...

Maybe some can help me.

share|improve this question

3 Answers 3

I'm not entirely sure that you understand what the article means by a fixed timestep.

requestAnimationFrame is defined as:

Tells the browser that you wish to perform an animation; this requests that the browser schedule a repaint of the window for the next animation frame.

The amount of time that passes between each invocation of the function varies based on computer specification, CPU load, etc. rAF simply does not guarantee consistency. As an example, consider this list of deltas (i.e. duration between invocations)[1]:

0.016 0.016 0.016 0.2 0.016 0.026 0.016 1.2

Obviously, this is not exactly going to fly as far as physics go, so what the article is trying to do is to make sure that your games updates are as regular as possible.

This means that when you get a delta that is 1/30 of a second (as opposed to 1/60), you need to invoke your games logic twice in that loop to ensure that the game's internal state is somewhat close to the viewer's expectation. It might sound scary to update the game's internal state multiple times per frame, but it may be necessary, depending on the circumstance.

Let's say you have a typical RPG hero on a tiled map, moving at a velocity of 1 tile per second east. This would mean that for each frame, he should move approximately 1/60th of a tile east. But say that a popup comes up, slowing the computer, and your next frame takes 1.2 seconds to come to the screen. The hero should have moved 1.2 tiles east in this time, but if you were to just hero.positionX += 1/60, he would have still only moved 1/60th of a tile.

To fix this, you'd need to fix your timestep, and integrate his position: hero.positionX += hero.velocityX * delta.

Here's an example of how you might accomplish this:

var lastCall = Date.now();
var accum = 0;
var dt = 1 / 60;
function mainLoop() {
    // Figure out how long it's been since the last invocation
    var delta = Date.now() - lastCall;

    //Cache the current timestep so we can figure out the next delta
    lastCall = Date.now();

    // Add the delta to the "accumulator"
    accum += delta;

    // As long as the accumulated time passed is greater than your "timestep"
    while (accum >= dt) {
        // Update the game's internal state (i.e. physics, logic, etc)
        game.update();

        // Subtract one "timestep" from the accumulator
        accum -= dt;
    }

    // Finally, render the current state to the screen
    game.render();
}
window.requestAnimationFrame(mainLoop);

[1] As a side note, last I'd heard, Chrome capped its FPS at 60, so you won't get better than that.

share|improve this answer

You only use the semi-fixed time step code once in your code. You'll use it in a main update loop. If you're processing an animation, you'd pass in your current time to set the animation to the appropriate frame. The time you pass in comes from the main update loop. The reason you're having a hard time figuring out where/how to use a while loop is because you wouldn't use one outside the main loop. If you were to recreate this time-step inside your animation function, you could only play one animation at a time, and everything would have to wait for that animation to finish.

share|improve this answer

requestAnimationFrame is here for animating, definitely not doing physics. So you should remove that part, and only put your rendering code in there. You also have a syntax error, I believe:

(function bla()
{

})();

And I don't see a need for a self executing function at all. Just create a normal one.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.