Games Rock.
Make Games in HTML5.

Paul Lewis
9th November 2011

Who am I?

I am a:

@aerotwist

http://aerotwist.com/+

Why would I bother making a game? Is it even worth trying in HTML5?

Good questions!

The Game Maker's To-do List

Drawing

We can haz optionz: 2D or 3D

2D Canvas

var canvas = document.createElement('canvas'),
    context = canvas.getContext('2d');

2D Canvas


http://caniuse.com/#search=canvas

2D Canvas - Performance

Canvas on iOS5 + A5 is
so fast that it's viable for simple games
Hakim El Hattab, Legend

3D Canvas

Better known as WebGL

WebGL

var canvas = document.createElement('canvas'),
    context = canvas.getContext('experimental-webgl'); // will be 'webgl' eventually

WebGL


http://aerotwist.com/a3
https://github.com/mrdoob/three.js
http://caniuse.com/#search=webgl

WebGL - Performance

Which context
should we use?

Drawing: decisions, decisions

A quick
sidenote...

requestAnimationFrame

/**
 * @see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 * @author The Paul Irish
 */
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          window.oRequestAnimationFrame      ||
          window.msRequestAnimationFrame     ||
          function(/* function */ callback, /* DOMElement */ element){
            window.setTimeout(callback, 1000 / 60);
          };
})();

Sound

Next level beats 'n' whooshes y'all.

Sound

Sound advice

What about the Audio APIs?

There are two different ones, one for Chrome and Firefox. Nothing for Opera, Safari or Internet Explorer.

Physics

Bouncy, bouncy!

Physics - The Problem

Three potential solutions

Otherwise we just go home and cry

1. Only do simple calculations

You may not be able to do this if the game relies
on more complex simulations

2. Reduce the framerate to 30fps

Give ourselves 32ms to do everything.
(Or we alternate between physics calculations and everything else, 16ms each)

3. Use a Worker

We can spawn a new OS-level thread just to handle the physics

Workers

var worker = new Worker('physics.js');

// initialisation where we send all the
// required world data to the worker
worker.postmessage(world.data);

// callback handler for incoming messages from the worker
worker.onmessage = function(evt) {
  processPhysicsDataFromWorker(evt.data);
};

// now start
worker.postmessage("start");

// later we stop
worker.postmessage("stop");

Workers

Workers - Performance

Input

Shake it baby!

Input

You can take input from the following:


https://wiki.mozilla.org/JoystickAPI
http://caniuse.com/#search=getusermedia

Input: Keyboard

function jamesBrownLovinMachine(evt) {

  switch(evt.keyCode) {

    // up arrow
    case 38: gitUpAh();
             break;

    // right arrow
    case 39: shakeItToThaLeft();
             break;

    // left arrow
    case 37: shakeItToThaRight();
             break;

    // down arrow
    case 40: gitDownAndParty();
             break;

  }
}

document.addEventListener('keydown', jamesBrownLovinMachine, false);
        

Input: Mouse

Let's assume some kind of FPS

function onMouseMove(evt) {
  var x = evt.pageX || evt.clientX,
      y = evt.pageY || evt.clientY;

  moveCrosshairTo(x, y);
}

function onMouseClick(evt) {
  fire();
}

document.addEventListener('mousemove', onMouseMove, false);
document.addEventListener('click', onMouseClick, false);
        

Mouse Lock

Coming soon!

Input: Accelerometer

Query the device. Really cool for mobile

// This is the Webkit style; Gecko does it differently!
function shakeItBabyShakeIt (evt) {

  // beta maps to z, gamma to x.
  // (If you have a gyro that should be alpha.)
  thingy.velocity.z += evt.beta;
  thingy.velocity.x += evt.gamma;

}

window.addEventListener('devicemotion', shakeItBabyShakeIt, false);
        

Input: Joystick

Heck. Yes. It's Firefox only for now. It's pretty much what
you'd expect API-wise.

window.addEventListener('MozJoyConnected', onJoystickConnect, false);
window.addEventListener('MozJoyDisconnected', onJoystickDisconnect, false);
window.addEventListener('MozJoyButtonDown', onJoystickButtonDown, false);
window.addEventListener('MozJoyButtonUp', onJoystickButtonUp, false);
window.addEventListener("MozJoyAxisMove", onJoystickAxisMove, false);

I want to see this in other browsers, though!

Input: Webcam

Take a video tag:

<video id="tehvideoz" autoplay></video>

And add a new source

/**
 * It's only a matter of time before someone
 * makes a Chatroulette clone. Terrifying.
 */
function onWebcamConnected(stream) {

  // get the video tag and add the webcam
  document.getElementById('tehvideoz').src = stream;
}

// ask the browser to hook us up
navigator.getUserMedia('video', onWebcamConnected, onWebcamError);

Webcam Demo

There's no way this can fail. It's only an alpha feature...  o_O

Other bits and pieces

I just have so much more love to give!

A simple performance test

var LENGTH  = 100000000,
    count   = 0,
    i       = 0;

// Tests a for loop
function one() {
  for(i = 0; i < LENGTH; i++) {
    count += i;
  }
}

// Tests a while going backwards
function two() {
  count = 0;
  while(i--) {
    count += i;
  }
}

// In Chrome
console.profile("loopTest");
one();
two();
console.profileEnd("loopTest");

On this Mac, one() took 53.25%
of the time; two() took 44.81%

A while loop going backwards was, in this case, faster than a for loop*

* In case you're wondering, the rest of the execution time was garbage collection and other overheads

If you're serious about
performance, use jsPerf

http://jsperf.com

If you aren't sure which way to do something, do it both ways and see which
works better.
John Carmack
Shouldn't I just be using a game engine?

...Maybe

Engines - Pros

Engines - Cons

Some Popular Engines


http://craftyjs.com/
http://impactjs.com/
http://www.isogenicengine.com/

Build your own

Some good advice given to me that I'll gladly pass on

A Game!

This just got real. For real.

Sketchout
by Fantasy Interactive

Conclusion

Conclusion

Questions?

Game over!

Sorry about the pun. Sorry. Sorry... Sorry