1. Intro to HTML5 Game Programming
James Williams
Wednesday, November 16, 2011
2. About Me
• Author of Learning HTML5 Game Programming
• Google+: +jameswilliams
• Twitter: @ecspike
• StartupBus Alum
2
Wednesday, November 16, 2011
3. StartupBus
• Originated as an idea to drive from SF to SXSW
• Developing a startup idea along the way
• Community building and networking
• StartupBus is coming to Europe!
• http://startupbus.com/europe
3
Wednesday, November 16, 2011
4. Other HTML5 Talks
• Introduction to SVG
–Filip Van Laenen (Nov 14th @ 9h30)
• Cross Platform Game Programming with PlayN
–Lilli Thompson (Nov 14th @ 21h00)
• Intro to HTML5 Game Programming - WebGL
–Me (Nov 16th @ 12h00)
• Working Off the Grid: HTML5 Offline
–Sam Dutton (Nov 16th @ 14h00)
4
Wednesday, November 16, 2011
7. What is HTML5?
• Evolution of the HTML spec
• New APIs and features dealing with
–audio and video
–canvas
–storage
–workers
–web sockets
7
Wednesday, November 16, 2011
8. Application Cache
• Permits applications to run offline
• Caching strategies:
–NETWORK
–FALLBACK
–CACHE
• Manifest file must be changed to update cache.
8
Wednesday, November 16, 2011
10. Web Workers
• Runs abitrary JavaScript on a background thread
• Workers can pass messages to/from the host
page
var worker = new Worker('task.js');
worker.onmessage = function(event) {
alert(event.data);
};
worker.postMessage('data');
/* in task.js */
self.onmessage = function(event) {
self.postMessage(“Msg: “+event.data)
}
10
Wednesday, November 16, 2011
11. WebSockets
• Similar to TCP sockets
• Permit bi-directional communication
• Data can take any form
• Functions/Handlers:
–onopen
–onmessage
–onerror
–onclose
–send
11
Wednesday, November 16, 2011
13. WebSQL
• Not supported by Firefox or IE
• Uses a SQLite-like language for DB access
• Not formally supported by the W3C
13
Wednesday, November 16, 2011
14. IndexedDB
• Endorsed by the W3C
• Uses a NoSQL-like language for DB access
• Transactional
• Reminiscent of MongoDB and CouchDB
14
Wednesday, November 16, 2011
15. WebStorage
• Supported by most browsers
• Usually capped at 5MB
• Key/value pairs
• Setting values:
localStorage.setItem(“a”, 42);
localStorage[“a”] = 42;
localStorage.a = 42;
• Retrieving values:
stuff = localStorage.getItem(“a”)
stuff = localStorage[“b”]
stuff = localStorage.b
15
Wednesday, November 16, 2011
16. Notifications API
• Surfaces Growl-like notifications
• Implemented in Chrome only
window.webkitNotifications.requestPermission();
• window.webkitNotifications.checkPermission();
– 0 allowed
– 1 denied
• Notification types
–Simple
–HTML
16
Wednesday, November 16, 2011
17. Audio Tag
• API to play audio in HTML5 pages
• Not well-suited for multiplexed sound
• Audio format support is spotty
<audio controls>
<source src="s.ogg" type="audio/ogg" />
<source src="s.mp3" type="audio/mpeg" />
Your browser does not support the audio
element.
</audio>
17
Wednesday, November 16, 2011
18. WebAudio API
• API for processing and synthesizing sound
• Allows playing multiple sounds
• Overcomes shortcomings of the audio tag
18
Wednesday, November 16, 2011
19. Video Tag
• Permits video playback without a plugin
• Video codec support is not consistent
• Can specify multiple files to ensure support
• Native controls and scrubbing
<video width="320" height="240" controls>
<source src="m.mp4" type="video/mp4" />
<source src="m.ogg" type="video/ogg" />
Your browser doesn’t support the video
tag.
</video>
19
Wednesday, November 16, 2011
21. Canvas2D
James Williams
Wednesday, November 16, 2011
22. Agenda - Canvas
• What is Canvas2D?
• Drawing Shapes
• Paths
• Fonts
• Pixel Manipulation
• Working with Video
• Creating a Tic-Tac-Toe Game
22
Wednesday, November 16, 2011
23. What is Canvas 2D?
• Immediate mode drawing API
• Capable of using images and video
• Scriptable with JavaScript
23
Wednesday, November 16, 2011
24. Drawing a Canvas
<html>
<head></head>
<body>
<canvas id=’c’ width=”400” height=”400"/>
</body>
</html>
24
Wednesday, November 16, 2011
25. Getting a Canvas2DContext
• Hook to draw on the canvas
var canvas = document.getElementById(“c”);
var ctx = c.getContext(“2d”);
• Capable of saving and restoring state
• Capable of applying 2D matrix transformations
25
Wednesday, November 16, 2011
31. Creating Tic-Tac-Toe
• Known in the UK as “Naughts and Crosses”
• Played by 2 players on a 3x3 grid
• Goal is to get 3 of the same object in a row
31
Wednesday, November 16, 2011
32. Drawing X’s
self.drawXSprite = function (x, y) {
var ctx = self.context;
// Save the canvas state and translate
ctx.save();
ctx.translate(x,y);
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(10,10);
ctx.lineTo(190,190);
ctx.moveTo(190,10);
ctx.lineTo(10,190);
ctx.stroke();
ctx.restore();
}
32
Wednesday, November 16, 2011
33. Drawing O’s
self.drawOSprite = function(x, y) {
var ctx = self.context;
// Save the canvas state and translate
ctx.save();
ctx.translate(x,y);
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(100,100, 90, 0, 2*Math.PI);
ctx.stroke();
// Restore canvas state
ctx.restore();
}
33
Wednesday, November 16, 2011
34. Drawing the Game Board
self.drawGameBoard = function() {
var ctx = self.context;
ctx.rect(200, 0, 1, 600);
ctx.rect(400, 0, 1, 600);
ctx.rect(0, 200, 600, 1);
ctx.rect(0, 400, 600, 1);
ctx.fill();
}
34
Wednesday, November 16, 2011
35. Tic-Tac-Toe AI - MiniMax
• Alternates trying to select the best possible move
• Recursively runs checking all paths
• Depth first search
• Can exceed limit in JS memory
35
Wednesday, November 16, 2011
36. MiniMax
function(board, currentPlayer) {
if (this.currentDepth == this.depthLimit) return 0;
if (TTT.checkForWin(board) == currentPlayer) return 1;
if (TTT.checkForWin(board) == this.getOtherPlayer
(currentPlayer))
return -1;
this.currentDepth++;
//truncated
var clone = TTT.cloneGameBoard(board);
var moves = TTT.generateMovesFromBoard(clone, currentPlayer);
// truncated
return bestMove;
}
36
Wednesday, November 16, 2011
38. Creating Copy Me
• Inspired by the game Simon
• The computer plays a series of tones
• The player must play them in the correct order
• Uses Trident.js to animate the squares
38
Wednesday, November 16, 2011
39. Trident.js
• JavaScript timeline animation library
• Allows for timelines to be interleaved
• Can animate any attribute accessible from JS
• Supports a number of easing functions
• https://github.com/kirillcool/trident-js
39
Wednesday, November 16, 2011
44. SVG
James Williams
Wednesday, November 16, 2011
45. Agenda - SVG
• What is SVG?
• Components
• Painting and Compositing
• Animation
• Raphael.js
• Creating a Video Poker Game
45
Wednesday, November 16, 2011
46. What is SVG?
• Stands for Scalable Vector Graphics
• Very mature API
• Uses XML to create objects
• Comparable to Canvas2D API
• Maintains full scene graph in the DOM
• Well suited for low count-low movement games
46
Wednesday, November 16, 2011
47. SVG vs Canvas
• Canvas requires data structures to track drawing
• With SVG, drawing is the data structure
• Canvas can draw hundreds of sprites
• SVG can get bogged down with the same
number
47
Wednesday, November 16, 2011
48. Raphaël.js
• JavaScript library to create SVG scenes
• Supports all major browsers including IE 6+
• Built-in easing functions for animation
• Built-in hooks for mouse interaction and gestures
• http://raphaeljs.com
48
Wednesday, November 16, 2011
49. Raphaël.js - Paper
• Comparable to the canvas tag
• Anchor for all drawing instructions
//adds a new svg tag to the DOM
var paper = Raphael(10, 50, 320, 200);
//adds a svg tag in the element with id “p”
var paper = Raphael("p", 320, 200);
49
Wednesday, November 16, 2011
50. Raphaël.js - Elements
• Rectangles
var rect = paper.rect(x, y, width, height,
[radius]);
• Circles
var circ = paper.circle(x, y, radius);
• Ellipses
var ellipse = paper.ellipse(x, y, rx, ry);
• Images
var image = paper.image(filename, x, y,
width, height);
• Arbitrary data can be attached with
data(key, val)
50
Wednesday, November 16, 2011
51. Raphaël.js - Text
• Text
var text = paper.text(x, y, textString);
• Formatted Text
var txt = r.print(x, y, textString,
font, fontSize);
• Cufón packages TrueType/Freetype fonts for use
with Raphael
• http://cufon.shoqolate.com/generate/
51
Wednesday, November 16, 2011
52. Color
• Can be specified by
–name (“red”, “blue”, “grey”)
–shorted hex color (#0F0)
–hex color (#00FF00)
–rgb/rgba
–hsb/hsba
–hsl/hsla
• Can be animated
52
Wednesday, November 16, 2011
53. Easing and Animation
• Any attribute can be animated
• Provide functions that define animation
• Linear
• BackIn / BackOut
• Bounce
• Acceleration
• Deceleration
• New easing functions can be created
53
Wednesday, November 16, 2011
54. Events
• Can take SVG objects as targets
• The following are supported
–drag
–mouseup / mousedown / mouseover / mousemove
–touchstart / touchmove / touchend / touchcancel
–mousehover
–click / dblclick
• Listeners are removed by calling the “un” version
Example: box.mouseunhover(function)
54
Wednesday, November 16, 2011
55. SVG Paths
• Text strings that describe how to draw objects
• Properly created paths can scale infinitely
• Operations
–moveto
–lineto (several variants)
–curveto (several variants)
–arc
–closepath
• // Draws a line from 10,10 to 90,90
var c = paper.path("M10 10L90 90");
55
Wednesday, November 16, 2011
56. Creating Video Poker
• Single player casino game
• Payout based on the bet * the final hand
• Uses a standard 52 card deck (svg-cards)
• Uses a mix of Coffeescript and JavaScript
• Underscore.js helps with evaluating
56
Wednesday, November 16, 2011
63. Agenda - WebGL
• What is WebGL?
• What is Three.js?
• Lighting, Shaders, and Materials
• Creating Meshes
• GLSL
• Exporters
• Animation
• Debugging
63
Wednesday, November 16, 2011
64. What is WebGL?
• Low-level 3D graphics context
• Hardware accelerated
• Supported by most modern browsers
• Syntax is based on OpenGL ES 2.0
64
Wednesday, November 16, 2011
65. Getting a WebGLContext
• Hook to draw on the canvas
var canvas = document.getElementById(“c”);
var ctx = c.getContext(“experimental-
webgl”);
65
Wednesday, November 16, 2011
66. What is Three.js?
• Abstraction layer over WebGL
• 3D scenegraph library
• Capable of rendering to
–Canvas2D
–WebGL
–SVG
• Exporters for popular 3D formats
• http://github.com/mrdoob/three.js
66
Wednesday, November 16, 2011
67. Initializing Three.js
function init() {
var HEIGHT = 480, WIDTH = 640;
// create a renderer, camera, and scene
renderer = new THREE.WebGLRenderer();
renderer.setSize (WIDTH, HEIGHT);
camera = /* truncated */
// create scene
scene = new THREE.Scene();
// add objects to scene
elem.appendChild(render.domElement);
}
67
Wednesday, November 16, 2011
68. Camera
• Eye point
• Field of vision
• Near / Far planes
• Target(LookAt) point
• Up vector
camera = new THREE.PerspectiveCamera(
FOV, ASPECT, NEAR, FAR, [target]
);
• Advanced Camera types
68
Wednesday, November 16, 2011
69. Creating Meshes
• Geometry
• Mesh
• Built-in geometries
• Vertex
new THREE.Vertex(
new Three.Vector3(0.0, 1.0, 0.0)
);
• Face
new THREE.Face3(0,1,2);
69
Wednesday, November 16, 2011
70. Creating Meshes
geometry = new THREE.Geometry();
geometry.vertices.push(vertex1);
geometry.vertices.push(vertex2);
geometry.vertices.push(vertex3);
geometry.faces.push(face1);
var triangle = new THREE.Mesh(geometry,
new THREE.MeshBasicMaterial( {
color: 0x00ff00 }
)
);
70
Wednesday, November 16, 2011
71. Creating Meshes
plane = new THREE.Mesh(
new THREE.Plane( 200, 200 ),
new THREE.MeshBasicMaterial( { color:
0xe0e0e0 }
)
);
scene.add( plane );
scene.add(triangle);
71
Wednesday, November 16, 2011
72. Lighting
• Ambient
• Point
• Directional
• SpotLight
new THREE.AmbientLight(hexColor);
new THREE.PointLight(hexColor, [intensity],
[distance]);
new THREE.DirectionalLight(hexColor,
[intensity], [distance], [castShadow]);
new THREE.SpotLight(hexColor, [intensity],
[distance], [castShadow]);
72
Wednesday, November 16, 2011
75. What is GLSL?
• High-level language with C-like syntax
• Targets the GPU and graphics pipeline
• A GLSL program consists of
–fragment shader
–vertex shader
• Content of shaders passed around as strings
• Shaders can be generated at run-time
75
Wednesday, November 16, 2011
76. Vertex Shaders
• Run once per vertex in a mesh
• Can alter color, position, texels, etc at that vertex
• Example shader:
<script id="shader-vs" type="x-shader/x-
vertex">
void main(void) {
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position, 1.0);
}
</script>
76
Wednesday, November 16, 2011
77. Fragment(Pixel) Shaders
• Run once per pixel in a mesh
• Can produce effects such as bump and env
mapping
• Example shader:
<script id="shader-vs" type="x-shader/x-
fragment">
void main(void) {
gl_FragColor = vec4(
0.0, 1.0, 0.0, 1.0
);
}
</script>
77
Wednesday, November 16, 2011
78. Shader Demo Code
function drawTriangle() {
var geometry, geoMaterial;
shaderMaterial = new
THREE.MeshShaderMaterial({
vertexShader: $('#v').get(0).innerHTML,
fragmentShader:$('#f').get(0).innerHTML,
vertexColors: true
});
/* truncated */
var triangle = new THREE.Mesh(
geometry, shaderMaterial
);
78
Wednesday, November 16, 2011
81. Communicating with Shaders
var uniforms;
uniforms = {
time: {type:"f", value:0.0}
}
shaderMaterial = new
THREE.MeshShaderMaterial({
uniforms: uniforms,
vertexShader:$('#v').get(0).innerHTML,
fragmentShader:$('#f').get(0).innerHTML,
});
81
Wednesday, November 16, 2011
82. Custom Shader
uniform float time;
void main(){
float r = cos(time);
float g = sin(time);
float b = tan(time);
gl_FragColor = vec4(r, 1.0 - g , b, 1.0);
}
82
Wednesday, November 16, 2011
83. Texturing
• Can load from images or use canvas data
• var texture = THREE.ImageUtils.loadTexture
( "tex.jpg" );
• texture = new THREE.Texture(image)
• Basic shapes precalculate texture coordinates
83
Wednesday, November 16, 2011
85. Texturing Example
var texture = THREE.ImageUtils.loadTexture
( "200407-bluemarble.jpg" );
var material = new THREE.MeshBasicMaterial
( { color: 0xFFFFFF,
ambient: 0xFFFFFF, map:texture } );
sphere = new THREE.Mesh(
new THREE.Sphere(32, 32, 32), material
);
scene.add(sphere);
85
Wednesday, November 16, 2011
95. Creating Conway’s Game of Life
• Zero-player game
• Cellular automation
• Our version is 3D
• Ported from Java with Prototype
95
Wednesday, November 16, 2011
96. Game of Life - Loading Model
function drawScene(m) {
window.suzanne = m;
grid = new CellsGrid(new LifeProperties
("{}"));
}
function loadModel() {
var loader = new THREE.JSONLoader();
loader.load( {
model: "suzanne.js",callback:drawScene
});
}
96
Wednesday, November 16, 2011
97. Game of Life - Creating a Cell
initialize: function(x,y,z) {
this.age = 0;
this.alive = (Math.random()<0.1) ?
true:false;
this.makeMaterial();
this.mesh = new THREE.Mesh(
window.suzanne, this.material
);
/* Set x, y, z positions
this.mesh.position.x = ...
*/
97
Wednesday, November 16, 2011
99. Circle Visualizer
• Extension to Google+
• Presents shared circles in a new way
• Other contributor: +JustinOrmont
• Code is barely two days old
99
Wednesday, November 16, 2011
100. Creating the Textures
for url in @imageURLs
img = new Image()
img.onload = () ->
count += 1
#truncated
self.generateTexture(this,
verticleOffset)
100
Wednesday, November 16, 2011
101. Creating the Textures
canvas = document.createElement("canvas")
ctx = canvas.getContext("2d")
# get image and place it on the canvas
ctx.drawImage(image, locX, locY, width,
height)
101
Wednesday, November 16, 2011
102. Creating the Textures
processedImg.onload = () ->
texture = new THREE.Texture
(processedImg)
texture.needsUpdate = true
self.textures.push(texture)
self.imagesLoaded++
if self.imagesLoaded ==
self.imageURLs.length
self.drawScene()
self.animate()
self.doneLoadingImages = true
102
Wednesday, November 16, 2011
103. WebGL Inspector
• Allows you to step through render instructions
• View texture assets and GLSL programs
• Capture individual frames
• Can be embedded or installed as Chrome
extension
• http://benvanik.github.com/WebGL-Inspector
103
Wednesday, November 16, 2011
104. Stats.js
• FPS - frames per second
• MS - how many millis it took to render the frame
• MB - the allocated megabytes
• Github: https://github.com/mrdoob/stats.js
104
Wednesday, November 16, 2011
108. Chrome Web Store
• $5(~3.60EUR) developer signup fee
• 95% of list price goes to the developer
• Supports
– in-app payments
– one-time purchase
– subscriptions (monthly and yearly)
• Payment requires Google Checkout Account
• More info: http://code.google.com/chrome/
webstore/docs/index.html
108
Wednesday, November 16, 2011
109. Web Store Manifest File
{
"name": "HTML5 Video Poker",
"description":"A video poker game created with CoffeeScript,
HTML5 Audio, and SVG",
"version":"1.0.2",
"icons":{
"16": "HTML5_Badge_16.png",
"32": "HTML5_Badge_32.png",
"128": "HTML5_Badge_128.png"
},
"app":{
"launch": {
"local_path":"index.html"
}
}
}
109
Wednesday, November 16, 2011
110. TapJS
• Limited Facebook integration
• Player Accounts, Leaderboards and badges
• Free subdomain to host your app
• Simply fill out a (really long) form and zip your
files
• Accepts the following file types
–html
–css
–js
–jpg, gif, and png
–mp3 and ogg
110
Wednesday, November 16, 2011
111. Mac App Store/Bodega
• Mac App Store
–Requires OS X 10.6.6 or higher(Snow Leopard)
–70/30 revenue split
–Restrictions on API access
–Sandboxing rules
–http://developer.apple.com/programs/mac/
• Bodega, alternate OS X app store
–Requires OS X 10.5.8 or higher(Leopard)
–93/7 revenue split
–http://appbodega.com/Developers.php
111
Wednesday, November 16, 2011
112. Ubuntu Software Center
• Very popular Linux distro
• Development Options:
–Quickly and PyGTK
–Mono
–Java
–Qt
• Supports both free and commercial apps
• 80% (Dev) / 20% (Canonical) split
• Requires PayPal for commercial apps
• More info: http://developer.ubuntu.com/
112
Wednesday, November 16, 2011
113. PhoneGap
• HTML5 App platform with native hooks
• Can access native features like:
–geolocation
–accelerometer
–storage
–audio/video/camera
• Nitobi acquired by Adobe
• Supports: iOS, Android, BB, WP7, WebOS
• PhoneGap Build
113
Wednesday, November 16, 2011
114. Thanks for coming
• Blog: http://jameswilliams.be/blog
• Google+: +jameswilliams
• Twitter: @ecspike
• http://github.com/jwill
114
Wednesday, November 16, 2011
115. Thanks for
coming!
Wednesday, November 16, 2011