Adding time-based animation

Adding time-based animation to our game engine

To add time-based animation to our game engine, we will be using the technique discussed in the previous lesson. This technique is now widely supported by browsers, and adds time-based animation to our game framework, through the timestamp parameter passed to the callback function (mainLoop) by the call to requestAnimationFrame(mainLoop).

Here is an online example of the game framework at JSBin: this time, the monster has a speed in pixels/s and we use time-based animation. Try it and verify the smoothness of the animation; the FPS counter on a Mac Book Pro core i7 shows 60 fps.

screenshot of the monster moving at 60 f/s

Now try this slightly modified version in which we added a delay inside the animation loop. This should slow down the frame rate.  On a Mac Book Pro + core i7, the frame-rate drops down to 37 fps. However, if you move the monster using the arrow keys, its speed on the screen is the same, excepting that it’s not as smooth as in the previous version, which ran at 60 fps.

screenshot of example that runs at 37 f/s

Here are the parts we changed

Declaration of the monster object – now the speed is in pixels/s instead of in pixels per frame

  1. // The monster !
  2. var monster = {
  3.    x:10,
  4.    y:10,
  5.    speed:100, // pixels/s this time !
  6. };

We added a timer(currentTime) function that returns the delta of the time elapsed since its last call

We refer to it from the game loop, to measure the time between frames. Notice that here we pass the delta as a parameter to the updateMonsterPosition call:

  1. function timer(currentTime) {
  2.    var delta = currentTime  oldTime;
  3.    oldTime = currentTime;
  4.    return delta;
  5. }
  6. var mainLoop = function(time){
  7.    //main function, called each frame
  8.    measureFPS(time);
  9.    // number of ms since last frame draw
  10.    delta = timer(time);
  11.    // Clear the canvas
  12.    clearCanvas();
  13.    // draw the monster
  14.    drawMyMonster(monster.x, monster.y);
  15.    // Check inputs and move the monster
  16.    updateMonsterPosition(delta);
  17.    // call the animation loop every 1/60th of second
  18.    requestAnimationFrame(mainLoop);
  19. };

Finally, we utilise the time-delta in the updateMonsterPosition(…) function

  1. function updateMonsterPosition(delta) {
  2.    
  3.    // Compute the incX and inY in pixels depending
  4.    // on the time elapsed since last redraw
  5.    monster.x += calcDistanceToMove(delta, monster.speedX);
  6.    monster.y += calcDistanceToMove(delta, monster.speedY);
  7.  }

Leave a comment