3 Answers
3

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.

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.

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.