|
1 | | -<!DOCTYPE html> |
| 1 | +<!DOCTYPE html> |
2 | 2 | <html> |
3 | 3 | <head> |
4 | 4 | <title>Javascript Tetris</title> |
|
22 | 22 | @media screen and (min-width: 800px) and (min-height: 800px) { #tetris { font-size: 2.00em; width: 750px; } #menu { width: 350px; height: 700px; } #upcoming { width: 175px; height: 175px; } #canvas { width: 350px; height: 700px; } } /* 35px chunks */ |
23 | 23 | @media screen and (min-width: 900px) and (min-height: 900px) { #tetris { font-size: 2.25em; width: 850px; } #menu { width: 400px; height: 800px; } #upcoming { width: 200px; height: 200px; } #canvas { width: 400px; height: 800px; } } /* 40px chunks */ |
24 | 24 | </style> |
25 | | -</head> |
| 25 | +</head> |
26 | 26 |
|
27 | | -<body> |
| 27 | +<body> |
28 | 28 |
|
29 | 29 | <div id="tetris"> |
30 | 30 | <div id="menu"> |
|
45 | 45 | // base helper methods |
46 | 46 | //------------------------------------------------------------------------- |
47 | 47 |
|
48 | | - function get(id) { return document.getElementById(id); }; |
49 | | - function hide(id) { get(id).style.visibility = 'hidden'; }; |
50 | | - function show(id) { get(id).style.visibility = null; }; |
51 | | - function html(id, html) { get(id).innerHTML = html; }; |
| 48 | + function get(id) { return document.getElementById(id); } |
| 49 | + function hide(id) { get(id).style.visibility = 'hidden'; } |
| 50 | + function show(id) { get(id).style.visibility = null; } |
| 51 | + function html(id, html) { get(id).innerHTML = html; } |
52 | 52 |
|
53 | | - function timestamp() { return new Date().getTime(); }; |
54 | | - function random(min, max) { return (min + (Math.random() * (max - min))); }; |
55 | | - function randomChoice(choices) { return choices[Math.round(random(0, choices.length-1))]; }; |
| 53 | + function timestamp() { return new Date().getTime(); } |
| 54 | + function random(min, max) { return (min + (Math.random() * (max - min))); } |
| 55 | + function randomChoice(choices) { return choices[Math.round(random(0, choices.length-1))]; } |
56 | 56 |
|
57 | 57 | if (!window.requestAnimationFrame) { // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ |
58 | | - window.requestAnimationFrame = window.webkitRequestAnimationFrame || |
59 | | - window.mozRequestAnimationFrame || |
60 | | - window.oRequestAnimationFrame || |
61 | | - window.msRequestAnimationFrame || |
| 58 | + window.requestAnimationFrame = window.webkitRequestAnimationFrame || |
| 59 | + window.mozRequestAnimationFrame || |
| 60 | + window.oRequestAnimationFrame || |
| 61 | + window.msRequestAnimationFrame || |
62 | 62 | function(callback, element) { |
63 | 63 | window.setTimeout(callback, 1000 / 60); |
64 | 64 | } |
|
112 | 112 | // |
113 | 113 | //------------------------------------------------------------------------- |
114 | 114 |
|
115 | | - var i = { id: 'i', size: 4, blocks: [0x0F00, 0x2222, 0x00F0, 0x4444], color: 'cyan' }; |
116 | | - var j = { id: 'j', size: 3, blocks: [0x44C0, 0x8E00, 0x6440, 0x0E20], color: 'blue' }; |
117 | | - var l = { id: 'l', size: 3, blocks: [0x4460, 0x0E80, 0xC440, 0x2E00], color: 'orange' }; |
118 | | - var o = { id: 'o', size: 2, blocks: [0xCC00, 0xCC00, 0xCC00, 0xCC00], color: 'yellow' }; |
119 | | - var s = { id: 's', size: 3, blocks: [0x06C0, 0x8C40, 0x6C00, 0x4620], color: 'green' }; |
120 | | - var t = { id: 't', size: 3, blocks: [0x0E40, 0x4C40, 0x4E00, 0x4640], color: 'purple' }; |
121 | | - var z = { id: 'z', size: 3, blocks: [0x0C60, 0x4C80, 0xC600, 0x2640], color: 'red' }; |
| 115 | + var i = { size: 4, blocks: [0x0F00, 0x2222, 0x00F0, 0x4444], color: 'cyan' }; |
| 116 | + var j = { size: 3, blocks: [0x44C0, 0x8E00, 0x6440, 0x0E20], color: 'blue' }; |
| 117 | + var l = { size: 3, blocks: [0x4460, 0x0E80, 0xC440, 0x2E00], color: 'orange' }; |
| 118 | + var o = { size: 2, blocks: [0xCC00, 0xCC00, 0xCC00, 0xCC00], color: 'yellow' }; |
| 119 | + var s = { size: 3, blocks: [0x06C0, 0x8C40, 0x6C00, 0x4620], color: 'green' }; |
| 120 | + var t = { size: 3, blocks: [0x0E40, 0x4C40, 0x4E00, 0x4640], color: 'purple' }; |
| 121 | + var z = { size: 3, blocks: [0x0C60, 0x4C80, 0xC600, 0x2640], color: 'red' }; |
122 | 122 |
|
123 | 123 | //------------------------------------------------ |
124 | 124 | // do the bit manipulation and iterate through each |
|
135 | 135 | ++row; |
136 | 136 | } |
137 | 137 | } |
138 | | - }; |
| 138 | + } |
139 | 139 |
|
140 | 140 | //----------------------------------------------------- |
141 | 141 | // check if a piece can fit into a position in the grid |
|
147 | 147 | result = true; |
148 | 148 | }); |
149 | 149 | return result; |
150 | | - }; |
| 150 | + } |
151 | 151 |
|
152 | 152 | function unoccupied(type, x, y, dir) { |
153 | 153 | return !occupied(type, x, y, dir); |
154 | | - }; |
| 154 | + } |
155 | 155 |
|
156 | 156 | //----------------------------------------- |
157 | 157 | // start with 4 instances of each piece and |
|
163 | 163 | pieces = [i,i,i,i,j,j,j,j,l,l,l,l,o,o,o,o,s,s,s,s,t,t,t,t,z,z,z,z]; |
164 | 164 | var type = pieces.splice(random(0, pieces.length-1), 1)[0]; |
165 | 165 | return { type: type, dir: DIR.UP, x: Math.round(random(0, nx - type.size)), y: 0 }; |
166 | | - }; |
| 166 | + } |
167 | 167 |
|
168 | 168 |
|
169 | 169 | //------------------------------------------------------------------------- |
|
189 | 189 | reset(); // reset the per-game variables |
190 | 190 | frame(); // start the first frame |
191 | 191 |
|
192 | | - }; |
| 192 | + } |
193 | 193 |
|
194 | 194 | function showStats() { |
195 | 195 | stats.domElement.id = 'stats'; |
196 | 196 | get('menu').appendChild(stats.domElement); |
197 | | - }; |
| 197 | + } |
198 | 198 |
|
199 | 199 | function addEvents() { |
200 | 200 | document.addEventListener('keydown', keydown, false); |
201 | 201 | window.addEventListener('resize', resize, false); |
202 | | - }; |
| 202 | + } |
203 | 203 |
|
204 | 204 | function resize(event) { |
205 | 205 | canvas.width = canvas.clientWidth; // set canvas logical size equal to its physical size |
|
210 | 210 | dy = canvas.height / ny; // (ditto) |
211 | 211 | invalidate(); |
212 | 212 | invalidateNext(); |
213 | | - }; |
| 213 | + } |
214 | 214 |
|
215 | 215 | function keydown(ev) { |
216 | 216 | var handled = false; |
|
229 | 229 | } |
230 | 230 | if (handled) |
231 | 231 | ev.preventDefault(); // prevent arrow keys from scrolling the page (supported in IE9+ and all other browsers) |
232 | | - }; |
| 232 | + } |
233 | 233 |
|
234 | 234 | //------------------------------------------------------------------------- |
235 | 235 | // GAME LOGIC |
236 | 236 | //------------------------------------------------------------------------- |
237 | 237 |
|
238 | | - function play() { hide('start'); reset(); playing = true; }; |
239 | | - function lose() { show('start'); setVisualScore(); playing = false; }; |
240 | | - |
241 | | - function setVisualScore(n) { vscore = n || score; invalidateScore(); }; |
242 | | - function setScore(n) { score = n; setVisualScore(n); }; |
243 | | - function addScore(n) { score = score + n; }; |
244 | | - function clearScore() { setScore(0); }; |
245 | | - function clearRows() { setRows(0); }; |
246 | | - function setRows(n) { rows = n; step = Math.max(speed.min, speed.start - (speed.decrement*rows)); invalidateRows(); }; |
247 | | - function addRows(n) { setRows(rows + n); }; |
248 | | - function getBlock(x,y) { return (blocks && blocks[x] ? blocks[x][y] : null); }; |
249 | | - function setBlock(x,y,type) { blocks[x] = blocks[x] || []; blocks[x][y] = type; invalidate(); }; |
| 238 | + function play() { hide('start'); reset(); playing = true; } |
| 239 | + function lose() { show('start'); setVisualScore(); playing = false; } |
| 240 | + |
| 241 | + function setVisualScore(n) { vscore = n || score; invalidateScore(); } |
| 242 | + function setScore(n) { score = n; setVisualScore(n); } |
| 243 | + function addScore(n) { score = score + n; } |
| 244 | + function clearScore() { setScore(0); } |
| 245 | + function clearRows() { setRows(0); } |
| 246 | + function setRows(n) { rows = n; step = Math.max(speed.min, speed.start - (speed.decrement*rows)); invalidateRows(); } |
| 247 | + function addRows(n) { setRows(rows + n); } |
| 248 | + function getBlock(x,y) { return (blocks && blocks[x] ? blocks[x][y] : null); } |
| 249 | + function setBlock(x,y,type) { blocks[x] = blocks[x] || []; blocks[x][y] = type; invalidate(); } |
250 | 250 | function clearBlocks() { blocks = []; invalidate(); } |
251 | | - function clearActions() { actions = []; }; |
252 | | - function setCurrentPiece(piece) { current = piece || randomPiece(); invalidate(); }; |
253 | | - function setNextPiece(piece) { next = piece || randomPiece(); invalidateNext(); }; |
| 251 | + function clearActions() { actions = []; } |
| 252 | + function setCurrentPiece(piece) { current = piece || randomPiece(); invalidate(); } |
| 253 | + function setNextPiece(piece) { next = piece || randomPiece(); invalidateNext(); } |
254 | 254 |
|
255 | 255 | function reset() { |
256 | 256 | dt = 0; |
|
260 | 260 | clearScore(); |
261 | 261 | setCurrentPiece(next); |
262 | 262 | setNextPiece(); |
263 | | - }; |
| 263 | + } |
264 | 264 |
|
265 | 265 | function update(idt) { |
266 | 266 | if (playing) { |
|
271 | 271 | if (dt > step) { |
272 | 272 | dt = dt - step; |
273 | 273 | drop(); |
274 | | - } |
| 274 | + } |
275 | 275 | } |
276 | | - }; |
| 276 | + } |
277 | 277 |
|
278 | 278 | function handle(action) { |
279 | 279 | switch(action) { |
|
282 | 282 | case DIR.UP: rotate(); break; |
283 | 283 | case DIR.DOWN: drop(); break; |
284 | 284 | } |
285 | | - }; |
| 285 | + } |
286 | 286 |
|
287 | 287 | function move(dir) { |
288 | 288 | var x = current.x, y = current.y; |
|
300 | 300 | else { |
301 | 301 | return false; |
302 | 302 | } |
303 | | - }; |
| 303 | + } |
304 | 304 |
|
305 | | - function rotate(dir) { |
| 305 | + function rotate() { |
306 | 306 | var newdir = (current.dir == DIR.MAX ? DIR.MIN : current.dir + 1); |
307 | 307 | if (unoccupied(current.type, current.x, current.y, newdir)) { |
308 | 308 | current.dir = newdir; |
309 | 309 | invalidate(); |
310 | 310 | } |
311 | | - }; |
| 311 | + } |
312 | 312 |
|
313 | 313 | function drop() { |
314 | 314 | if (!move(DIR.DOWN)) { |
|
322 | 322 | lose(); |
323 | 323 | } |
324 | 324 | } |
325 | | - }; |
| 325 | + } |
326 | 326 |
|
327 | 327 | function dropPiece() { |
328 | 328 | eachblock(current.type, current.x, current.y, current.dir, function(x, y) { |
329 | 329 | setBlock(x, y, current.type); |
330 | 330 | }); |
331 | | - }; |
| 331 | + } |
332 | 332 |
|
333 | 333 | function removeLines() { |
334 | 334 | var x, y, complete, n = 0; |
|
348 | 348 | addRows(n); |
349 | 349 | addScore(100*Math.pow(2,n-1)); // 1: 100, 2: 200, 3: 400, 4: 800 |
350 | 350 | } |
351 | | - }; |
| 351 | + } |
352 | 352 |
|
353 | 353 | function removeLine(n) { |
354 | 354 | var x, y; |
355 | 355 | for(y = n ; y >= 0 ; --y) { |
356 | 356 | for(x = 0 ; x < nx ; ++x) |
357 | 357 | setBlock(x, y, (y == 0) ? null : getBlock(x, y-1)); |
358 | 358 | } |
359 | | - }; |
| 359 | + } |
360 | 360 |
|
361 | 361 | //------------------------------------------------------------------------- |
362 | 362 | // RENDERING |
|
378 | 378 | drawScore(); |
379 | 379 | drawRows(); |
380 | 380 | ctx.restore(); |
381 | | - }; |
| 381 | + } |
382 | 382 |
|
383 | 383 | function drawCourt() { |
384 | 384 | if (invalid.court) { |
|
395 | 395 | ctx.strokeRect(0, 0, nx*dx - 1, ny*dy - 1); // court boundary |
396 | 396 | invalid.court = false; |
397 | 397 | } |
398 | | - }; |
| 398 | + } |
399 | 399 |
|
400 | 400 | function drawNext() { |
401 | 401 | if (invalid.next) { |
|
409 | 409 | uctx.restore(); |
410 | 410 | invalid.next = false; |
411 | 411 | } |
412 | | - }; |
| 412 | + } |
413 | 413 |
|
414 | 414 | function drawScore() { |
415 | 415 | if (invalid.score) { |
416 | 416 | html('score', ("00000" + Math.floor(vscore)).slice(-5)); |
417 | 417 | invalid.score = false; |
418 | 418 | } |
419 | | - }; |
| 419 | + } |
420 | 420 |
|
421 | 421 | function drawRows() { |
422 | 422 | if (invalid.rows) { |
423 | 423 | html('rows', rows); |
424 | 424 | invalid.rows = false; |
425 | 425 | } |
426 | | - }; |
| 426 | + } |
427 | 427 |
|
428 | 428 | function drawPiece(ctx, type, x, y, dir) { |
429 | 429 | eachblock(type, x, y, dir, function(x, y) { |
430 | 430 | drawBlock(ctx, x, y, type.color); |
431 | 431 | }); |
432 | | - }; |
| 432 | + } |
433 | 433 |
|
434 | 434 | function drawBlock(ctx, x, y, color) { |
435 | 435 | ctx.fillStyle = color; |
436 | 436 | ctx.fillRect(x*dx, y*dy, dx, dy); |
437 | 437 | ctx.strokeRect(x*dx, y*dy, dx, dy) |
438 | | - }; |
| 438 | + } |
439 | 439 |
|
440 | 440 | //------------------------------------------------------------------------- |
441 | 441 | // FINALLY, lets run the game |
|
445 | 445 |
|
446 | 446 | </script> |
447 | 447 |
|
448 | | -</body> |
| 448 | +</body> |
449 | 449 | </html> |
0 commit comments