HTML5 and Other Modern Browser Game Tech

Jeff Timanus, November 2nd, 2011


Use arrow keys, space, or click on left and right of slides to navigate.
Ctrl/Command +/- to change zoom.

Hi, I'm Jeff Timanus. Also known as twiz@google.com.

This talk is an overview

Platform Reach & Success

HTML5 & Related Technologies

Engines & Mobile Distribution

Learning more

Chrome has 200+ Million Active Users

As of Q3, 2011

How did they do that?

With some of this HTML5 browser tech ...

Box2D for Physics

Demo Source:savagelook.com

WebGL for Fast Graphics

Demo Source: helloracer.com

HTML5 Canvas 2d for Fallback

HTML5 App Cache for Offline Play

Chrome Web Store

Chrome Web Store

Platform Reach & Success

HTML5 & Related Technologies

Engines & Mobile Distribution

Learning more

Here we go . . .

Canvas2D

SVG

CSS 3D

WebGL

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

Canvas2D

Canvas2D - Overview

Canvas2D - API

Canvas2D - Basic Example

<canvas id="e" width="200" height="100"></canvas>
<script type='text/javascript'>
  var context =
    document.getElementById("e").getContext("2d");
  var cat = new Image();
  cat.src = "images/cat.png";
  cat.onload = function() {
    context.drawImage(cat, 0, 0);
  };
</script>

Canvas2D - Fill and Stroke Sample

// Draw eyes
ctx.fillRect(160, 130, 20, 80);
ctx.fillRect(220, 130, 20, 80);

// Draw mouth
ctx.beginPath();
ctx.moveTo(100, 230); // Start smile
ctx.bezierCurveTo(100, 230, 200, 380, 300, 230);

ctx.moveTo(219, 298); // Start tongue
ctx.bezierCurveTo(278, 351, 315, 315, 277, 258);

ctx.lineWidth = 20;
ctx.stroke();

Adapted from an IE 9 sample

Canvas2D - Availability

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

Scalable Vector Graphics (SVG) - Overview

SVG - Sample Content

SVG - Inline Sample

<!DOCTYPE html><html><body> 
  <svg id="mySVG">
    <circle id="circle0" 
            cx="100" cy="75" r="50" 
            fill="grey" 
            stroke="black" 
            stroke-width="10"
            onmousedown="alert('Hello World!');"><\circle> 
    <text x="200" y="70">Hello World</text> 
  </svg>
  ...
 
Hello World

SVG - Script Sample

<script>
    var circle = document.createElementNS(
        "http://www.w3.org/2000/svg", "circle");
    circle.setAttribute('cx', 90); 
    circle.setAttribute('cy', 90);
    circle.setAttribute('r', 50); 
    circle.setAttribute('stroke', 'grey');
    circle.setAttribute('stroke-width', 10);
    circle.setAttribute('onmousedown', "alert('No, me!');");
    document.getElementById("svg0").appendChild(circle);
</script>

SVG - Availability

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets

WebStorage

Web workers

Native Client

WebGL - Canvas3D

WebGL - Some Impressive Demos


Check out more cool demos at chromeexperiments.com!

WebGL - Just a few libraries ...

WebGL - Sample Spinning Box

WebGL - Sample Vertex Shader

<script id="vshader" type="x-shader/x-vertex">
  uniform mat4 u_modelViewProjMatrix;
  uniform mat4 u_normalMatrix;
  uniform vec3 lightDir;
  
  attribute vec3 vNormal;
  attribute vec4 vColor;
  attribute vec4 vPosition;
  
  varying float v_Dot;    
  varying vec4 v_Color;
  
  void main() 
  {
    gl_Position = u_modelViewProjMatrix * vPosition;
    v_Color = vColor;
    vec4 transNormal = u_normalMatrix * vec4(vNormal, 0.0);
    v_Dot = max(dot(transNormal.xyz, lightDir), 0.0);
  }
</script>

WebGL - Sample Fragment Shader

<script id="fshader" type="x-shader/x-fragment"> 
    varying float v_Dot;
    varying vec4 v_Color;
 
    void main()
    {
        gl_FragColor = vec4(v_Color.xyz * v_Dot, v_Color.a);
    }
</script>

WebGL - Basic Setup

var gl = canvas.getContext(“webgl”, args);

gl.createShader(shaderType);
gl.shaderSource(shader, shaderScript.text);
gl.compileShader(shader);

var colors = new Uint8Array( [ 0,0,1,1,  0,0,1,1,  0,0,1,1,  0,0,1,1,
            1,0,0,1,  1,0,0,1,  1,0,0,1,  1,0,0,1,
            //…
box.colorObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, box.colorObject);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

WebGL - Basic Draw Function

function drawPicture(gl) {
  reshape(gl);

  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  // Setup a model/view matrix.
  mvMatrix.makeIdentity();
  mvMatrix.rotate(20, 1,0,0);
  mvMatrix.rotate(currentAngle, 0,1,0);
  //...

  gl.drawElements(gl.TRIANGLES, box.numIndices,
                  gl.UNSIGNED_BYTE, 0);
  //...
}

WebGL - Availability

requestAnimationFrame

Aka: Your render loop!

Status Quo: Draw blindly!

setInterval(draw, 16) setInterval(draw, 16)

setInterval(draw, 16) setInterval(draw, 16)
setInterval(draw, 16) setInterval(draw, 16)
setInterval(draw, 16) setInterval(draw, 16)......

The Browser calls YOU!

function draw() {
    //... Do drawing work, then ask to be called again:
    window.requestAnimationFrame(draw);
}

// Kick off first frame:
window.requestAnimationFrame(draw);

requestAnimationFrame - Recommended Shim

// shim layer with setTimeout fallback – 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);
    };
})();

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets

WebStorage

Web workers

Native Client

CSS 3D
Cascading Style Sheets - 3D Transformations

CSS 3D Transforms - Basic Example

<!DOCTYPE html><html><body> 
<style>
  .css3ddemo {       -webkit-transition: all .4s ease-in-out;
                     -webkit-transform-style:preserve-3d; }
  .css3ddemo:hover { -webkit-transform:rotateY(15deg); }</style>
<div style="-webkit-perspective: 400;">
  <iframe class="css3ddemo" src="http://sijm.ca/2011/"></iframe>
</div></body></html>

CSS3D - Availability

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

<audio> - Overview

var audio = new Audio();
audio.addEventListener("canplaythrough", 
     function () { audio.play(); });
audio.src = "treasure.ogg";
<audio controls="controls">
  <source src="horse.ogg" type="audio/ogg" />
  <source src="horse.mp3" type="audio/mp3" />
  Your browser does not support the audio element.
</audio>

<audio> - Caveats & Issues

<audio> - Availability

Web Audio API

Audio - Fallback

SoundManager2

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

<video> - Overview

videoElement.play();  
videoElement.addEventListener("timeupdate",
                              updateTexture, true);

function updateTexture() {  
  gl.bindTexture(gl.TEXTURE_2D, cubeTexture);  
  gl.texImage2D(gl.TEXTURE_2D, 0, videoElement, true);  
  gl.generateMipmap(gl.TEXTURE_2D);
}

<video> - Availability

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

WebSockets

WebSockets - Availability

Node.JS - Overview

Javascript on your Server

Node.JS - Hello World

Server - Reply with 'Hello World'

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

Awesome demo: Plink

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

Saving Data on the Client

Just a few options . . .

WebStorage - Overview

localStorage["levels-unlocked"] = 5 // or .getItem() / .setItem()
localStorage.removeItem("inventory-special-item")
localStorage.clear(); // Remove everything

WebStorage - Availability

IndexedDB

File System

Source: html5wow.com

Application Cache

Application Cache - Availability

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

Web workers - Sample

Multi-threading Javascript

main.js (main thread):

var worker = new Worker('doWork.js');
worker.addEventListener('message', 
  function(e) { console.log('Worker said: ', e.data); }, false);
worker.postMessage('Hello World');  // Send data to our worker.

doWork.js (worker thread):

self.addEventListener('message', function(e) {
  self.postMessage(e.data + “? ” + e.data + “!”); }, false);

// Output: "Worker said: Hello World? Hello World!"

Web workers - Availability

Canvas2D

SVG

WebGL

CSS 3D

Audio

<video>

WebSockets & Server Tech

WebStorage

Web workers

Native Client

Native Client

Native Client - Security Model

Native Client - First Game Launch

Porting Star Legends

From Android to NaCl in 8 Weeks


8 weeks to access to 200+ millon 7-day active users in Chrome

gonacl.com

Did we miss something?

Platform Reach & Success

HTML5 & Related Technologies

Engines & Mobile Distribution

Learning more

HTML5 game engines

Mobile and HTML5

C/C++ iOS games Ported to JavaScript/WebGL

Mandreel port of Great Little War Game

Platform Reach & Success

HTML5 & Related Technologies

Engines & Mobile Distribution

Learning more

Industry Momentum

New Game - HTML5 Game Development Conference

New Game : The Conference for HTML5 Game Developers

Nov 1-2, San Francisco
Sponsors include Google & Microsoft

Blogs, Articles

HTML5 Game Dev Books

Isometric Social Real-Time Games with HTML5, CSS3, and JavaScript book cover Making Isometric Social Real-Time Games with HTML5, CSS3, and JavaScript

Learning HTML5 Game Programming book cover Learning HTML5 Game Programming

Challenges

Potential

Thanks!