Javascript - Can't Adjust FrameRate - requestanimationframe

前端 未结 7 2053
被撕碎了的回忆
被撕碎了的回忆 2021-02-06 03:50

I start the loop

function gameLoop(){
   update();
   draw();
   requestAnimFrame(gameLoop);
}

var requestAnimFrame =  window.requestAnimationFrame ||
                  


        
7条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-06 04:23

    The way browsers and javascript work makes it difficult to set up a fixed frame rate. Say you want to do something every one second, like updating and drawing. One way of doing that could be to call window.setTimeout() with a setting of one second. But the problem is that this is not that reliable, even if you configure a callback every second you can't be sure all callbacks will be in time. A high processor load, for example, could make the callbacks arrive much later than they should. And even if the callbacks would be on time, you have no control of when the actual drawing to the screen will happen.

    A better way of handling it is to accept the fact that you can't get a very precise timing of your calls, and instead, whenever you get a call, you calculate how much time has passed and act according to that. This means you'll let the system decide the frame rate, and you just take care of updating your animation or game depending on how much time that has passed.

    requestAnimationFrame is a newer functionality supported by most browsers by now that is especially useful for games. It will be called every time the browser is ready to draw, which is good. Then you will know that the updates and drawing you are doing will happen right before the actual frame is drawn to screen.

    Here's an example on how you could update your gameLoop to take the time difference into account.

    var lastTimestamp = +new Date;
    
    function gameLoop(timestamp) {
      var now = +new Date;
      var dt = now - lastTimestamp;
    
      // dt is the amount of time in ms that has passed since last call.
      // update takes this time difference (in seconds) and can then perform its
      // updates based on time passed.
      update(dt / 1000);
      draw();
      lastTimestamp = now;
      requestAnimationFrame(gameLoop);
    }
    

提交回复
热议问题