Building Browser Based Games Using HTML5 Marc OMorain Lead - - PowerPoint PPT Presentation

building browser based games using html5
SMART_READER_LITE
LIVE PREVIEW

Building Browser Based Games Using HTML5 Marc OMorain Lead - - PowerPoint PPT Presentation

Building Browser Based Games Using HTML5 Marc OMorain Lead Developer, Swrve @atmarc Who am I? Who are you? Outline Talk for about 40 minutes Take questions at the end Why ? Why do people use Lua? 1. Fast Iteration 15


slide-1
SLIDE 1

Marc O’Morain

Lead Developer, Swrve @atmarc

Building Browser Based Games Using HTML5

slide-2
SLIDE 2
slide-3
SLIDE 3

Who am I?

slide-4
SLIDE 4

Who are you?

slide-5
SLIDE 5

Outline

  • Talk for about 40 minutes
  • Take questions at the end
slide-6
SLIDE 6

Why ?

slide-7
SLIDE 7

Why do people use Lua?

slide-8
SLIDE 8
  • 1. Fast Iteration
slide-9
SLIDE 9

15 minutes to run the game!

slide-10
SLIDE 10
slide-11
SLIDE 11
slide-12
SLIDE 12

Bret Victor - “Inventing on Principle”

http://vimeo.com/36579366 http://worrydream.com

slide-13
SLIDE 13

Why do people use Lua?

slide-14
SLIDE 14
  • 2. Scripts Are Data
slide-15
SLIDE 15

Escape the Walled Garden

slide-16
SLIDE 16

Deliver the game directly to the player

slide-17
SLIDE 17

What am I going to talk about?

slide-18
SLIDE 18
slide-19
SLIDE 19

Topics: HTML The DOM Rendering Main Loop User Input iOS Web Apps Developer Tools Hosting Audio

slide-20
SLIDE 20

What type of game?

slide-21
SLIDE 21

HTML

slide-22
SLIDE 22

How do we run code?

slide-23
SLIDE 23

These tags make text <b>bold</b>.

slide-24
SLIDE 24

Some tags make text <i>slanted</i>.

slide-25
SLIDE 25

But a pair of <script> tags are different.

slide-26
SLIDE 26

#include <stdio.h> #include <stdlib.h> // Code always starts here int main(int argc, char** argv) { printf("Hello GDC\n"); return EXIT_SUCCESS; }

slide-27
SLIDE 27

<html> <head> <title>Hello GDC</title> <script src=”main.js” type=”text/javascript”> </script> </head> <body> <h1>Hello GDC</h1> <p>Welcome to San Francisco.</p> </body> </html>

slide-28
SLIDE 28

DOM

slide-29
SLIDE 29

The DOM is a tree exposed to JavaScript

document h1 p canvas body head title div div

slide-30
SLIDE 30

Rendering

slide-31
SLIDE 31

<canvas>

slide-32
SLIDE 32
slide-33
SLIDE 33

<html> <body> <canvas id="game"></canvas> </body> </html> html, body { width: 100%; height: 100%; margin: 0px; }

Make a canvas element that fills the screen

slide-34
SLIDE 34

// JavaScript var canvas = document.getElementById('game'); var context = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; context.strokeRect(32, 16, 128, 64);

t$ $

slide-35
SLIDE 35

var factory = new Image(); var house = new Image(); $(factory).load(function(){ context.drawImage(this, 10, 10); }).attr('src', ’factory.png'); $(house).load(function(){ context.drawImage(this, 140, 10); }).attr('src', ’shop.png');

slide-36
SLIDE 36

<canvas> performance

slide-37
SLIDE 37

Avoid <canvas> context changes

slide-38
SLIDE 38

<canvas> layers

slide-39
SLIDE 39

<canvas> text rendering

slide-40
SLIDE 40

WebGL

slide-41
SLIDE 41

CSS

slide-42
SLIDE 42

<html> <body> <div class="sprite" id="house"></div> <div class="sprite" id="factory"></div> </body> </html>

slide-43
SLIDE 43

.sprite { width: 128px; height: 128px; position : absolute; background-repeat: no-repeat; } #house { background-image: url(shop.png); left: 32px; } #factory { background-image: url(factory.png); left: 150px; }

slide-44
SLIDE 44

<html> <body> <div class="game" id="game"></div> </body> </html> var game = $(‘#game’); var house = $('<div class="sprite" style="width: 128px; height: 128px; background-image: url(house.png); position: absolute; background-repeat: no-repeat;"></div>'); game.append(house);

slide-45
SLIDE 45

// Firefox sprite.style.MozTransform = ‘matrix(a, c, b, d, tx, ty)’ // Where a, b, c, d build the transformation matrix // ┌ ┐ // │ a b │ // │ c d │ // └ ┘ // and tx, ty are the translate values. // See https://developer.mozilla.org/en/CSS/transform // Webkit based browsers - hardware accelerated var transform = 'translate3d(10px, 20px, 1px) rotate(0.3rad) scale(2, 2)’; sprite.style.webkitTransform = transform;

slide-46
SLIDE 46

Animation

slide-47
SLIDE 47

Sprite Sheets

slide-48
SLIDE 48

// canvas var frame = 2; var width = 32; var height = 32; context.drawImage(particles, frame * width, 0, width, height, x, y, width, height);

slide-49
SLIDE 49

// using CSS var frame = 2; var width = 32; var height = 32; var element = ... // Set the ‘background-position’ CSS attribute element.style.backgroundPositionX =

  • (frame * width) + 'px';
slide-50
SLIDE 50

128 x 128 (5 frames)

slide-51
SLIDE 51

Single 128 x 128 image smaller 32 x 32

  • verlay animation
slide-52
SLIDE 52

Main Loop

slide-53
SLIDE 53

var intervalID = window.setInterval(func, delay); var intervalID = window.setTimeout (func, delay);

slide-54
SLIDE 54

Request Animation Frame

slide-55
SLIDE 55

// How long does update take to call? // How long since last call to update? var update = function(dt) { var now = new Date(); var now = window.mozAnimationStartTime; }

slide-56
SLIDE 56

User Input

slide-57
SLIDE 57

Keyboard

slide-58
SLIDE 58

Mouse + Touch

slide-59
SLIDE 59

Mouse

slide-60
SLIDE 60

One click handler on the <canvas> What did the user click on?

slide-61
SLIDE 61
slide-62
SLIDE 62
slide-63
SLIDE 63
slide-64
SLIDE 64

Build a tree of all clickable

  • bjects in the scene
slide-65
SLIDE 65

Click Maps

slide-66
SLIDE 66

What happens player clicks on a background pixel? Need to be able to tell when a click is on the image

slide-67
SLIDE 67
slide-68
SLIDE 68

00000000000000001111000000000000 00000000000000001111011000000000 00000000000000001111111100000000 00000000000000001111111100000000 00000000000000111111111100000000 00000000001111111111111100000000 00000011111111111111111100000000 00011111111111111111111111000000 00011111111111111111111111110000 00011111111111111111111111110000 00011111111111111111111111110000 00011111111111111111111111111100 00111111111111111111111111111110 00000011111111111111111111100000 00000000001111111111111000000000 00000000000000111100000000000000

Original Image 128x128 Text array 32x32 pixel click map Black and white alpha channel

slide-69
SLIDE 69

Render image to off-screen <canvas>

slide-70
SLIDE 70
slide-71
SLIDE 71

Do the work once on the server

slide-72
SLIDE 72

var click_map_data = { 'factory.png' : '00000000000000001111000000000000' + '00000000000000001111011000000000' + '00000000000000001111111100000000' + '00000000000000001111111100000000' + '00000000000000111111111100000000' + '00000000001111111111111100000000' + '00000011111111111111111100000000' + '00011111111111111111111111000000' + '00011111111111111111111111110000' + '00011111111111111111111111110000' + '00011111111111111111111111110000' + '00011111111111111111111111111100' + '00111111111111111111111111111110' + '00000011111111111111111111100000' + '00000000001111111111111000000000' + '00000000000000111100000000000000', 'burger.png' : '00000000000001111110000000000000' + '00000000000111111111100000000000' + '00000000000111111111110000000000' +

slide-73
SLIDE 73

var click_map_data={"factory.png":"00000000000000001111000000000000000000000 0000000111101100000000000000000000000001111111100000000000000000000000011111 1110000000000000000000000111111111100000000000000000011111111111111000000000 0000011111111111111111100000000000111111111111111111111110000000001111111111 1111111111111110000000111111111111111111111111100000001111111111111111111111 1110000000111111111111111111111111111000011111111111111111111111111111000000 0111111111111111111111000000000000000111111111111100000000000000000000000111 100000000000000","burger.png":"000000000000011111100000000000000000000000011 1111111100000000000000000000001111111111100000000000000000011111111111111110 0000000000000111111111111111111111000000000011111111111111111111110000000000 1111111111111111111111000000000011111111111111111111110000000000011111111111 1111111111000001111111111111111111111111111111111111111111111111111111111111 111000001O111111111111111111111000000000000011111111111111100000000000000000 00001111111000000000000"};

slide-74
SLIDE 74

Touch

slide-75
SLIDE 75

iOS Click Delay

slide-76
SLIDE 76

300ms

slide-77
SLIDE 77

var mouse_start_x = 0; var mouse_start_y = 0; var mouse_x = 0; var mouse_y = 0; document.ontouchstart = function(event) { mouse_x = mouse_start_x = event.pageX; mouse_y = mouse_start_y = event.pageY; }

slide-78
SLIDE 78

document.ontouchmove = function(event) { mouse_x = event.pageX; mouse_y = event.pageY; } document.ontouchend = function(event) { if (distance_between(mouse_x, mouse_y, start_mouse_x, start_mouse_y) > 10){ click_at(mouse_x, mouse_y); } }

slide-79
SLIDE 79

Pinch

slide-80
SLIDE 80

var pinch_distance = 0; document.ontouchmove = function(event){ if (event.touches.length == 2){ var t0 = event.touches[0]; var t1 = event.touches[1]; var d = distance_between(t0.pageX, t0.pageY, t1.pageX, t1.pageY);

  • n_pinch(d - pinch_distance);

pinch_distance = d; } }

slide-81
SLIDE 81
slide-82
SLIDE 82

Throttling Input

slide-83
SLIDE 83

Event Based Callbacks Can Fire Multiple Times Per Frame

slide-84
SLIDE 84

iOS Web Apps

slide-85
SLIDE 85

pp$

$

<html> <head> <meta name="viewport" content="width=device‐width, initial‐scale=1.0, maximum-scale=1.0, user-scalable=0" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" /> <link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone4.png" /> <link rel="apple-touch-startup-image" href="/startup.png">

slide-86
SLIDE 86

Development Tools

slide-87
SLIDE 87

Writing Code

slide-88
SLIDE 88
slide-89
SLIDE 89

gcc -Wall -Werror

slide-90
SLIDE 90

Unit Tests Jasmine

http://pivotal.github.com/jasmine/

slide-91
SLIDE 91

describe("Maths", function() { it("should be able to add numbers", function() { expect(2 + 2).toEqual(4); }); describe("subtraction", function() { it("should be able to subtract numbers", function() { expect(10 - 2).toEqual(8); expect(100 - 90).toEqual(10); }); }); });

slide-92
SLIDE 92

Profiling

slide-93
SLIDE 93

Performance Profiling

slide-94
SLIDE 94
slide-95
SLIDE 95
slide-96
SLIDE 96
slide-97
SLIDE 97
slide-98
SLIDE 98

Garbage Collection

slide-99
SLIDE 99

So what code allocates memory?

slide-100
SLIDE 100

var dict = { foo: 'bar', baz: 'qux' };

slide-101
SLIDE 101

var object = new FooBar();

slide-102
SLIDE 102

var string = 'Head ' + tail;

slide-103
SLIDE 103

var string = 'foo'; var dict = { foo: 1 }; // Closes over dict and string var func = function(){ return dict[string]; };

slide-104
SLIDE 104

How can we refactor code to avoid allocation?

slide-105
SLIDE 105

Change code like this: // This code is going to // allocate a dictionary on each // iteration of the loop // unless the compiler/JIT can // prove otherwise. for (i=0; i < items.length; i++){ items[i].foo({x: i, y: 2 * i}); }; To be more like this: // Allocate the dictionary once var pos = {x: 0, y: 0}; for (i=0; i < items.length; i++){ // Update the one dictionary // in the body of the loop. pos.x = i; pos.y = 2 * i; items[i].foo(pos); };

slide-106
SLIDE 106
slide-107
SLIDE 107

Debugging

slide-108
SLIDE 108
slide-109
SLIDE 109
slide-110
SLIDE 110

Hosting

slide-111
SLIDE 111

Local web server http://localhost:8080

slide-112
SLIDE 112
slide-113
SLIDE 113

And you launch your game...

slide-114
SLIDE 114
slide-115
SLIDE 115

Browser Cache

slide-116
SLIDE 116

HTML5 Audio

slide-117
SLIDE 117
slide-118
SLIDE 118

Use Flash

slide-119
SLIDE 119

Questions?

(please use the microphone)

marc.omorain@swrve.com @atmarc