KEMBAR78
5 tips for your HTML5 games | KEY
5 tips for your
HTML5 games
 @ernesto_jimenez
 Lead Developer, Six to Start
5 things that
   might be helpful
developing your games
the game loop
GAME LOOP
function updateGame () {
  processPlayerInput();
  updateGameLogic();
  draw();
  setTimeout(updateGame, 25);
}
GAME LOOP


• Drawing   is the most expensive

• Game   is locked while running the update

• We   are consuming resources
you don’t always need
     a game loop
frame buffering
ABOUT FLICKERING
function draw() {
  var canvas = document.getElementById('visible-canvas');
  var context = canvas.getContext('2d');
  context.fillStyle = 'red';
  // Draw 200x200 square in x: 0 y: 0
  context.fillRect(0, 0, 200, 200);
  // Draw 200x200 square in x: 200 y: 200
  context.fillRect(0, 0, 200, 200);
}
ABOUT FLICKERING
function draw() {
  var canvas = document.getElementById('visible-canvas');
  var context = canvas.getContext('2d');
  context.fillStyle = 'red';
  // Draw 200x200 square in x: 0 y: 0
  context.fillRect(0, 0, 200, 200);
  // Draw 200x200 square in x: 200 y: 200
  context.fillRect(0, 0, 200, 200);
}
ABOUT FLICKERING
function draw() {
  var canvas = document.getElementById('visible-canvas');
  var context = canvas.getContext('2d');
  context.fillStyle = 'red';
  // Draw 200x200 square in x: 0 y: 0
  context.fillRect(0, 0, 200, 200);
  // Draw 200x200 square in x: 200 y: 200
  context.fillRect(0, 0, 200, 200);
}
USE TWO CANVAS




off-screen      visible
1) DRAW OFF-SCREEN




off-screen     visible
2) COPY THE RESULT




off-screen      visible
RIGHT FRAME BUFFER

function draw() {
  var buffer = document.createElement('canvas');
  var canvas = document.getElementById('visible-canvas');
  buffer.width = canvas.width;
  buffer.height = canvas.height;

    var buffer_context = buffer.getContext('2d');
    var context = canvas.getContext('2d');

    buffer_context.fillStyle = 'red';
    // Draw ...

    context.drawImage(buffer, 0, 0);
}
WRONG FRAME BUFFER
function draw() {
  var buffer = document.createElement('canvas');
  var canvas = document.getElementById('visible-canvas');
  buffer.width = canvas.width;
  buffer.height = canvas.height;

 var buffer_context = buffer.getContext('2d');
 var context = canvas.getContext('2d');

 buffer_context.fillStyle = 'red';
 // Draw ...

  var data = buffer_context.getImageData(0, 0, canvas.width,
canvas.height);
  context.putImageData(data, 0, 0);
}
avg. time for 1,000 frame-buffer operations in Firefox 4.0b7
              right frame buffer                 wrong frame buffer


 7,000ms
 6,300ms
 5,600ms
 4,900ms
 4,200ms
 3,500ms
 2,800ms
 2,100ms
 1,400ms
  700ms
    0ms
                                   plain color
frame buffer is not
always useful right now
    Browsers are repainting the canvas after your JS
expensive drawing
getImageData
     &
putImageData
avg. time for 1,000 fillRect in Firefox 4.0b7
                 fillRect 100x100px                   fillRect 500x500px


4,000ms

3,500ms

3,000ms

2,500ms

2,000ms

1,500ms

1,000ms

 500ms

   0ms
             plain color         3 stops linear gradient       blurred shadow
fillText is cool
but it is expensive
think outside of the
       canvas
1 GAME != 1 CANVAS
combine different
canvas to produce a
   single screen
images from Belén Albeza (@ladybenko)
images from Belén Albeza (@ladybenko)
dirty rectangles
redraw only those areas
   that have changed
images from Belén Albeza (@ladybenko)
images from Belén Albeza (@ladybenko)
HIGH
     PERFORMANCE
      JAVASCRIPT
         Nicholas C. Zakas




http://oreilly.com/catalog/9780596802806

5 tips for your HTML5 games

  • 1.
    5 tips foryour HTML5 games @ernesto_jimenez Lead Developer, Six to Start
  • 2.
    5 things that might be helpful developing your games
  • 3.
  • 4.
    GAME LOOP function updateGame() { processPlayerInput(); updateGameLogic(); draw(); setTimeout(updateGame, 25); }
  • 5.
    GAME LOOP • Drawing is the most expensive • Game is locked while running the update • We are consuming resources
  • 6.
    you don’t alwaysneed a game loop
  • 7.
  • 8.
    ABOUT FLICKERING function draw(){ var canvas = document.getElementById('visible-canvas'); var context = canvas.getContext('2d'); context.fillStyle = 'red'; // Draw 200x200 square in x: 0 y: 0 context.fillRect(0, 0, 200, 200); // Draw 200x200 square in x: 200 y: 200 context.fillRect(0, 0, 200, 200); }
  • 9.
    ABOUT FLICKERING function draw(){ var canvas = document.getElementById('visible-canvas'); var context = canvas.getContext('2d'); context.fillStyle = 'red'; // Draw 200x200 square in x: 0 y: 0 context.fillRect(0, 0, 200, 200); // Draw 200x200 square in x: 200 y: 200 context.fillRect(0, 0, 200, 200); }
  • 10.
    ABOUT FLICKERING function draw(){ var canvas = document.getElementById('visible-canvas'); var context = canvas.getContext('2d'); context.fillStyle = 'red'; // Draw 200x200 square in x: 0 y: 0 context.fillRect(0, 0, 200, 200); // Draw 200x200 square in x: 200 y: 200 context.fillRect(0, 0, 200, 200); }
  • 11.
  • 12.
  • 13.
    2) COPY THERESULT off-screen visible
  • 14.
    RIGHT FRAME BUFFER functiondraw() { var buffer = document.createElement('canvas'); var canvas = document.getElementById('visible-canvas'); buffer.width = canvas.width; buffer.height = canvas.height; var buffer_context = buffer.getContext('2d'); var context = canvas.getContext('2d'); buffer_context.fillStyle = 'red'; // Draw ... context.drawImage(buffer, 0, 0); }
  • 15.
    WRONG FRAME BUFFER functiondraw() { var buffer = document.createElement('canvas'); var canvas = document.getElementById('visible-canvas'); buffer.width = canvas.width; buffer.height = canvas.height; var buffer_context = buffer.getContext('2d'); var context = canvas.getContext('2d'); buffer_context.fillStyle = 'red'; // Draw ... var data = buffer_context.getImageData(0, 0, canvas.width, canvas.height); context.putImageData(data, 0, 0); }
  • 16.
    avg. time for1,000 frame-buffer operations in Firefox 4.0b7 right frame buffer wrong frame buffer 7,000ms 6,300ms 5,600ms 4,900ms 4,200ms 3,500ms 2,800ms 2,100ms 1,400ms 700ms 0ms plain color
  • 17.
    frame buffer isnot always useful right now Browsers are repainting the canvas after your JS
  • 18.
  • 19.
    getImageData & putImageData
  • 20.
    avg. time for1,000 fillRect in Firefox 4.0b7 fillRect 100x100px fillRect 500x500px 4,000ms 3,500ms 3,000ms 2,500ms 2,000ms 1,500ms 1,000ms 500ms 0ms plain color 3 stops linear gradient blurred shadow
  • 21.
    fillText is cool butit is expensive
  • 22.
    think outside ofthe canvas
  • 23.
    1 GAME !=1 CANVAS
  • 24.
    combine different canvas toproduce a single screen
  • 25.
    images from BelénAlbeza (@ladybenko)
  • 26.
    images from BelénAlbeza (@ladybenko)
  • 27.
  • 28.
    redraw only thoseareas that have changed
  • 29.
    images from BelénAlbeza (@ladybenko)
  • 30.
    images from BelénAlbeza (@ladybenko)
  • 32.
    HIGH PERFORMANCE JAVASCRIPT Nicholas C. Zakas http://oreilly.com/catalog/9780596802806