jsicon

js: the requestAnimationFrame() game loop

Historically, web/js based apps had to basically set their own “loop” using setInterval or setTimeout. There’s actually not a huge downside to using those, except when framerate becomes an issue. So now we can use requestAnimationFrame(). It has a number of uses, but the simplest is just to have it handle the entire game loop.

Essentially RAF calls a callback function every time the interpreter can come up for air. This combined with tracking the delta in time between frames can allow you to handle changes in framerate more smoothly.

In the implementation below calling myGame.actionLoop() calls recurse(), which then has requestAnimationFrame call the recurse loop repeatedly. I’ve broken the specific game logic out into the function var doThisEveryFrame just to clearly illustrate the effect.

myGame.actionLoop = function() {
    var lastFrameTime;
    var deltaT;
    var lowEnd = 1;
    var highEnd = 160;

    var doThisEveryFrame = function(timeDiff){
      myGame.updatePhysics(timeDiff);
      myGame.updateLogic(timeDiff);
      myGame.renderChangesToScreen();
    };

    function recurse( thisFrameTime ) {
        window.requestAnimationFrame(recurse);
        thisFrameTime = thisFrameTime && thisFrameTime > 5000 ? thisFrameTime : window.performance.now();
        lastFrameTime = lastFrameTime || thisFrameTime;
        deltaT = thisFrameTime - lastFrameTime;

        if (deltaT >  highEnd){
          deltaT = highEnd;
        }
        if(deltaT > lowEnd){
          doThisEveryFrame(deltaT);
          lastFrameTime = thisFrameTime;
        }
    }
  recurse();
};

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>