Created
July 24, 2011 19:18
-
-
Save lachezar/1102964 to your computer and use it in GitHub Desktop.
Game of Life (Javascript + HTML5's Canvas)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Game of Life</title> | |
</head> | |
<body> | |
<canvas id="canvas" width="400" height="300">There should be a canvas somewhere here.... :-/</canvas> | |
<script type="text/javascript"> | |
var canvas = document.getElementById('canvas'); | |
var context = canvas.getContext('2d'); | |
context.fillRect(0, 0, canvas.width, canvas.height); | |
var THE_BLACK = 0; | |
var THE_WHITE = 0xFF; | |
function spawn(n, data) { | |
for (var i = 0; i < n; i++) { | |
var k = parseInt(Math.random()*canvas.width*canvas.height)*4; | |
data.data[k] = THE_WHITE; | |
data.data[k+1] = THE_WHITE; | |
data.data[k+2] = THE_WHITE; | |
} | |
} | |
function applyRules(data, newdata) { | |
// highly optimized | |
var width = canvas.width*4; | |
var d = data.data; | |
var nd = newdata.data; | |
var cw = canvas.width; | |
var ch = canvas.height; | |
var base = 0; | |
for (var i = 0; i < d.length/4; i++) { | |
var x = i % cw; | |
var y = parseInt(i / cw); | |
var cnt = 0; | |
if (x > 0 && d[base-4] != THE_BLACK) cnt++; | |
if (x < cw-1 && d[base+4] != THE_BLACK) cnt++; | |
if (x > 0 && y > 0 && d[base-4-width] != THE_BLACK) cnt++; | |
if (y > 0 && d[base-width] != THE_BLACK) cnt++; | |
if (x < cw-1 && y > 0 && d[base+4-width] != THE_BLACK) cnt++; | |
if (x > 0 && y < ch-1 && d[base-4+width] != THE_BLACK) cnt++; | |
if (y < ch-1 && d[base+width] != THE_BLACK) cnt++; | |
if (x < cw-1 && y < ch-1 && d[base+4+width] != THE_BLACK) cnt++; | |
var color = null; | |
if (d[base] == THE_BLACK && cnt == 3) { | |
color = THE_WHITE; | |
} else if (!(d[base] != THE_BLACK && (cnt == 3 || cnt == 2))) { | |
color = THE_BLACK; | |
} | |
if (color !== null) { | |
nd[base] = nd[base+1] = nd[base+2] = color; | |
} | |
base += 4; | |
} | |
// dead cell with 3 neightbours - alive | |
// live cell with 2 or 3 neightbours - still alive | |
// all other cases - dead | |
} | |
function getLiveNeighbours(id, data) { | |
var x = id % canvas.width; | |
var y = parseInt(id / canvas.width); | |
var cnt = 0; | |
for (var i = -1; i < 2; i++) { | |
for (var j = -1; j < 2; j++) { | |
if ((i != 0 || j != 0) && | |
!(x+i < 0 || x+i >= canvas.width || y+j < 0 || y+j >= canvas.height) && | |
data.data[4*((y+j)*canvas.width+(x+i))] != THE_BLACK) { | |
cnt++; | |
} | |
} | |
} | |
return cnt; | |
} | |
function mainLoop() { | |
var start = new Date(); | |
var data = context.getImageData(0, 0, canvas.width, canvas.height); | |
var newdata = context.getImageData(0, 0, canvas.width, canvas.height); | |
spawn(parseInt(0.02*canvas.width*canvas.height), data); | |
applyRules(data, newdata); | |
context.putImageData(newdata, 0, 0); | |
console.log('time delta', new Date().getTime() - start.getTime()); | |
} | |
var data = context.getImageData(0, 0, canvas.width, canvas.height); | |
spawn(parseInt(0.2*canvas.width*canvas.height), data); | |
context.putImageData(data, 0, 0); | |
setInterval(mainLoop, 50); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment