Michael Henretty

HTML5 Game Development, for GNUbs

  • We will cover:
    • Game Loops, Object Pools
    • Basic Physics, Collision Detection
    • Resource Loading, Performance
  • We WON'T cover:
    • Making a website
    • Javascript programming
    • Animation, Deployment, Monetization

The Goals

  • Learn GameDev Building Blocks
  • Turn WebDev into GameDev
  • Understand performance basics
  • Such inspire, games WOW
  •     WOW

Game Loop

  • Engine room of your game
  • Iterative as fast as possible
  • 2 Parts for each:
    • Ticking - updating game state
    • Drawing - display game state to screen
  • In HTML5, we use requestAnimationFrame

Game Loop - cont.



function singleStepOfGameLoop() {
  updateGameState();
  drawEverything();
  requestAnimationFrame(singleStepOfGameLoop);
}

// kick us off
singleStepOfGameLoop();

        

Game Loop - cont.

  • Question:
    • what happens when things slow down?
    • are you tracking time???

Game Loop - cont.


function singleStepOfGameLoop() {
  var delta = getMsSinceLastUpdate()
  while (delta > 16) {
    updateGameState();
    delta = delta - 16
  }
  drawEverything();
  requestAnimationFrame(singleStepOfGameLoop);
}

// kick us off
singleStepOfGameLoop();
        

Game Loop - cont.

Questions?

Object Pools

  • Allocating memory in JavaScript is easy
    • deallocating is even easier
  • but... GARBAGE COLLECTION!
    • no control over when
    • worst enemy, causes jank
  • For example, particles
    • lots of little moving objects

Without Object Pools


function emitParticle(x, y) {
  var p = new Particle();
  p.x = x;
  p.y = y;
  p.animate();
}
        

With Object Pools


funtion ParticlePool() {
  this.particles = [];
  for (var i = 0; i < 100; i++) {
    particles[i] = new Particle();
  }
}

ParticlePool.prototype.get = function() {
  return this.particles.pop();
}

ParticlePool.prototype.release = function(particle) {
  this.particles.push(particle);
}

      

With Object Pools cont.


function emitParticle(pool, x, y) {
  var p = pool.get();
  p.x = x;
  p.y = y;
  p.animate();
  // return so we can release it later
  return p;
}

// then sometime later
function onParticleComplete(pool, particle) {
  pool.release(particle);
}
        

Object Pool

Questions?

Physics

Collision Detection

  • Ojects have to interact realistically
  • But how??
    • use MATHS dummy

    Let's see MATHS

    Code

  • Fix it for FREE STUFF!!

Resource Loading

  • HTML5 games aren't packaged
    • they load, just like a webpage
  • Media (images, sounds), load async
    • hard to know when everything is ready
    • especially in JavaScript

Naive Resource Loading


var img = new Image();
img.onload = function() { console.log('yay?'); }
img.src = 'http://fake.image.url/cats.png'
startGame();
        

Let's add progress

function loadNextImage() {
  if (count === waitingFor) {
    startGame();
    return;
  }

  var img = new Image();
  img.src = getAnotherImageUrl();

  img.onload = loadNextImage;
  count++;
  updateProgressBar(count);
}

// kick it off
loadNextImage();
          

smooooooth


function onLoadComplete() {
  count++;
  updateProgressBar(count);
  if (count === waitingFor) {
    startGame();
  }
}

function loadImages() {
  for (var i = 0; i < total; i++) {
    var img = new Image();
    img.src = getAnotherImageUrl();
    img.onload = onLoadComplete;
  }
}
          

Questions?

Performance

  • What makes a good game Good?
    • Beautiful Artwork
    • Great Music
    • Compelling Story
    • GRAPHICS!!!

Graphics

  • Resolution & Framerate
    • Movies are 24 fps
    • Games should aim for 60 fps
  • Higher framerate = smoother, more fun
  • Which would you rather play?

Moral of the Story

  • Don't do a lot of work in the tick
    • 60fps -> 16ms per tick
    • tick fast!
    • Profiler can help

The end?