├── README.md
├── demo
├── 00-canvas.html
├── 01-physics.html
├── 02-keys.html
├── 03-bitmap.html
├── 04-bullets.html
├── 05-enemies.html
├── 06-spritesheets.html
├── 07-collisions.html
├── 08-text.html
├── 09-background.html
├── 10-sound.html
├── 11-states.html
├── 12-polish.html
├── img
│ ├── bg-fade.png
│ ├── bg.png
│ ├── bullet.png
│ ├── enemyRun.png
│ ├── sparkle.png
│ ├── title.png
│ └── whitemage.png
├── index.html
├── keymaster.js
└── sound
│ ├── hit.wav
│ ├── hurt.wav
│ └── missile.wav
└── jsGameDemo.pdf
/README.md:
--------------------------------------------------------------------------------
1 | Here's a step-by-step guide to building a game from scratch in JavaScript.
2 |
3 | [Play it!](http://mimswright.com/games/huge-gamedemo/)
4 |
5 | Be sure to *View Source*!
6 |
--------------------------------------------------------------------------------
/demo/00-canvas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/demo/01-physics.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
144 |
145 |
146 |
147 | click to add more
148 |
149 |
--------------------------------------------------------------------------------
/demo/02-keys.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/demo/03-bitmap.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/demo/04-bullets.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/demo/05-enemies.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
228 |
229 |
230 |
231 |
232 |
--------------------------------------------------------------------------------
/demo/06-spritesheets.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
252 |
253 |
254 |
255 |
256 |
--------------------------------------------------------------------------------
/demo/07-collisions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
286 |
287 |
288 |
289 |
290 |
--------------------------------------------------------------------------------
/demo/08-text.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
314 |
315 |
316 |
317 |
318 |
--------------------------------------------------------------------------------
/demo/09-background.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
341 |
342 |
343 |
344 |
345 |
--------------------------------------------------------------------------------
/demo/10-sound.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
350 |
351 |
352 |
353 |
354 |
--------------------------------------------------------------------------------
/demo/11-states.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
415 |
416 |
417 |
418 |
419 |
--------------------------------------------------------------------------------
/demo/12-polish.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
7 |
8 |
493 |
494 |
495 |
496 |
497 |
--------------------------------------------------------------------------------
/demo/img/bg-fade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/bg-fade.png
--------------------------------------------------------------------------------
/demo/img/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/bg.png
--------------------------------------------------------------------------------
/demo/img/bullet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/bullet.png
--------------------------------------------------------------------------------
/demo/img/enemyRun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/enemyRun.png
--------------------------------------------------------------------------------
/demo/img/sparkle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/sparkle.png
--------------------------------------------------------------------------------
/demo/img/title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/title.png
--------------------------------------------------------------------------------
/demo/img/whitemage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/img/whitemage.png
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Game!
6 |
11 |
12 |
13 | jsGameDemo
14 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/demo/keymaster.js:
--------------------------------------------------------------------------------
1 | // keymaster.js
2 | // (c) 2011 Thomas Fuchs
3 | // keymaster.js may be freely distributed under the MIT license.
4 |
5 | ;(function(global){
6 | var k,
7 | _handlers = {},
8 | _mods = { 16: false, 18: false, 17: false, 91: false },
9 | _scope = 'all',
10 | // modifier keys
11 | _MODIFIERS = {
12 | '⇧': 16, shift: 16,
13 | '⌥': 18, alt: 18, option: 18,
14 | '⌃': 17, ctrl: 17, control: 17,
15 | '⌘': 91, command: 91
16 | },
17 | // special keys
18 | _MAP = {
19 | backspace: 8, tab: 9, clear: 12,
20 | enter: 13, 'return': 13,
21 | esc: 27, escape: 27, space: 32,
22 | left: 37, up: 38,
23 | right: 39, down: 40,
24 | del: 46, 'delete': 46,
25 | home: 36, end: 35,
26 | pageup: 33, pagedown: 34,
27 | ',': 188, '.': 190, '/': 191,
28 | '`': 192, '-': 189, '=': 187,
29 | ';': 186, '\'': 222,
30 | '[': 219, ']': 221, '\\': 220
31 | },
32 | _downKeys = [];
33 |
34 | for(k=1;k<20;k++) _MODIFIERS['f'+k] = 111+k;
35 |
36 | // IE doesn't support Array#indexOf, so have a simple replacement
37 | function index(array, item){
38 | var i = array.length;
39 | while(i--) if(array[i]===item) return i;
40 | return -1;
41 | }
42 |
43 | // handle keydown event
44 | function dispatch(event, scope){
45 | var key, handler, k, i, modifiersMatch;
46 | key = event.keyCode;
47 |
48 | if (index(_downKeys, key) == -1) {
49 | _downKeys.push(key);
50 | }
51 |
52 | // if a modifier key, set the key. property to true and return
53 | if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
54 | if(key in _mods) {
55 | _mods[key] = true;
56 | // 'assignKey' from inside this closure is exported to window.key
57 | for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
58 | return;
59 | }
60 |
61 | // see if we need to ignore the keypress (ftiler() can can be overridden)
62 | // by default ignore key presses if a select, textarea, or input is focused
63 | if(!assignKey.filter.call(this, event)) return;
64 |
65 | // abort if no potentially matching shortcuts found
66 | if (!(key in _handlers)) return;
67 |
68 | // for each potential shortcut
69 | for (i = 0; i < _handlers[key].length; i++) {
70 | handler = _handlers[key][i];
71 |
72 | // see if it's in the current scope
73 | if(handler.scope == scope || handler.scope == 'all'){
74 | // check if modifiers match if any
75 | modifiersMatch = handler.mods.length > 0;
76 | for(k in _mods)
77 | if((!_mods[k] && index(handler.mods, +k) > -1) ||
78 | (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
79 | // call the handler and stop the event if neccessary
80 | if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
81 | if(handler.method(event, handler)===false){
82 | if(event.preventDefault) event.preventDefault();
83 | else event.returnValue = false;
84 | if(event.stopPropagation) event.stopPropagation();
85 | if(event.cancelBubble) event.cancelBubble = true;
86 | }
87 | }
88 | }
89 | }
90 | };
91 |
92 | // unset modifier keys on keyup
93 | function clearModifier(event){
94 | var key = event.keyCode, k,
95 | i = index(_downKeys, key);
96 |
97 | // remove key from _downKeys
98 | if (i >= 0) {
99 | _downKeys.splice(i, 1);
100 | }
101 |
102 | if(key == 93 || key == 224) key = 91;
103 | if(key in _mods) {
104 | _mods[key] = false;
105 | for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
106 | }
107 | };
108 |
109 | function resetModifiers() {
110 | for(k in _mods) _mods[k] = false;
111 | for(k in _MODIFIERS) assignKey[k] = false;
112 | }
113 |
114 | // parse and assign shortcut
115 | function assignKey(key, scope, method){
116 | var keys, mods, i, mi;
117 | if (method === undefined) {
118 | method = scope;
119 | scope = 'all';
120 | }
121 | key = key.replace(/\s/g,'');
122 | keys = key.split(',');
123 |
124 | if((keys[keys.length-1])=='')
125 | keys[keys.length-2] += ',';
126 | // for each shortcut
127 | for (i = 0; i < keys.length; i++) {
128 | // set modifier keys if any
129 | mods = [];
130 | key = keys[i].split('+');
131 | if(key.length > 1){
132 | mods = key.slice(0,key.length-1);
133 | for (mi = 0; mi < mods.length; mi++)
134 | mods[mi] = _MODIFIERS[mods[mi]];
135 | key = [key[key.length-1]];
136 | }
137 | // convert to keycode and...
138 | key = key[0]
139 | key = _MAP[key] || key.toUpperCase().charCodeAt(0);
140 | // ...store handler
141 | if (!(key in _handlers)) _handlers[key] = [];
142 | _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
143 | }
144 | };
145 |
146 | // Returns true if the key with code 'keyCode' is currently down
147 | // Converts strings into key codes.
148 | function isPressed(keyCode) {
149 | if (typeof(keyCode)=='string') {
150 | if (keyCode.length == 1) {
151 | keyCode = (keyCode.toUpperCase()).charCodeAt(0);
152 | } else {
153 | return false;
154 | }
155 | }
156 | return index(_downKeys, keyCode) != -1;
157 | }
158 |
159 | function getPressedKeyCodes() {
160 | return _downKeys;
161 | }
162 |
163 | function filter(event){
164 | var tagName = (event.target || event.srcElement).tagName;
165 | // ignore keypressed in any elements that support keyboard data input
166 | return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
167 | }
168 |
169 | // initialize key. to false
170 | for(k in _MODIFIERS) assignKey[k] = false;
171 |
172 | // set current scope (default 'all')
173 | function setScope(scope){ _scope = scope || 'all' };
174 | function getScope(){ return _scope || 'all' };
175 |
176 | // delete all handlers for a given scope
177 | function deleteScope(scope){
178 | var key, handlers, i;
179 |
180 | for (key in _handlers) {
181 | handlers = _handlers[key];
182 | for (i = 0; i < handlers.length; ) {
183 | if (handlers[i].scope === scope) handlers.splice(i, 1);
184 | else i++;
185 | }
186 | }
187 | };
188 |
189 | // cross-browser events
190 | function addEvent(object, event, method) {
191 | if (object.addEventListener)
192 | object.addEventListener(event, method, false);
193 | else if(object.attachEvent)
194 | object.attachEvent('on'+event, function(){ method(window.event) });
195 | };
196 |
197 | // set the handlers globally on document
198 | addEvent(document, 'keydown', function(event) { dispatch(event, _scope) }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48
199 | addEvent(document, 'keyup', clearModifier);
200 |
201 | // reset modifiers to false whenever the window is (re)focused.
202 | addEvent(window, 'focus', resetModifiers);
203 |
204 | // set window.key and window.key.set/get/deleteScope, and the default filter
205 | global.key = assignKey;
206 | global.key.setScope = setScope;
207 | global.key.getScope = getScope;
208 | global.key.deleteScope = deleteScope;
209 | global.key.filter = filter;
210 | global.key.isPressed = isPressed;
211 | global.key.getPressedKeyCodes = getPressedKeyCodes;
212 |
213 | if(typeof module !== 'undefined') module.exports = key;
214 |
215 | })(this);
216 |
--------------------------------------------------------------------------------
/demo/sound/hit.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/sound/hit.wav
--------------------------------------------------------------------------------
/demo/sound/hurt.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/sound/hurt.wav
--------------------------------------------------------------------------------
/demo/sound/missile.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/demo/sound/missile.wav
--------------------------------------------------------------------------------
/jsGameDemo.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mimshwright/jsGameDemo/a10349555632ac2bd3ba8fad00ab536d685424d5/jsGameDemo.pdf
--------------------------------------------------------------------------------