Created
December 7, 2012 23:17
-
-
Save worenga/4237432 to your computer and use it in GitHub Desktop.
A CodePen by Benedikt Wolters.
This file contains hidden or 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
<h1>Conway's Game of Live</h1> | |
<canvas id="c"></canvas> |
This file contains hidden or 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
$(document).ready( | |
function () { | |
var lastTime = 0; | |
var vendors = ['ms', 'moz', 'webkit', 'o']; | |
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { | |
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; | |
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; | |
} | |
if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) { | |
var currTime = new Date().getTime(); | |
var timeToCall = Math.max(0, 16 - (currTime - lastTime)); | |
var id = window.setTimeout(function () { | |
callback(currTime + timeToCall); | |
}, | |
timeToCall); | |
lastTime = currTime + timeToCall; | |
return id; | |
}; | |
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { | |
clearTimeout(id); | |
}; | |
var GameOfLife = {}; | |
GameOfLife.Dead = 0; | |
GameOfLife.Alive = 1; | |
GameOfLife.glider = new Array(); | |
//Glider.. | |
GameOfLife.glider[0] = new Array(); | |
GameOfLife.glider[0][0] = GameOfLife.Dead; | |
GameOfLife.glider[0][1] = GameOfLife.Alive; | |
GameOfLife.glider[0][2] = GameOfLife.Dead; | |
GameOfLife.glider[1] = new Array(); | |
GameOfLife.glider[1][0] = GameOfLife.Dead; | |
GameOfLife.glider[1][1] = GameOfLife.Dead; | |
GameOfLife.glider[1][2] = GameOfLife.Alive; | |
GameOfLife.glider[2] = new Array(); | |
GameOfLife.glider[2][0] = GameOfLife.Alive; | |
GameOfLife.glider[2][1] = GameOfLife.Alive; | |
GameOfLife.glider[2][2] = GameOfLife.Alive; | |
GameOfLife.LWSShip = new Array(); | |
GameOfLife.LWSShip[0]= new Array(); | |
GameOfLife.LWSShip[0][0] = GameOfLife.Dead; | |
GameOfLife.LWSShip[0][1] = GameOfLife.Alive; | |
GameOfLife.LWSShip[0][2] = GameOfLife.Alive; | |
GameOfLife.LWSShip[0][3] = GameOfLife.Alive; | |
GameOfLife.LWSShip[1]= new Array(); | |
GameOfLife.LWSShip[1][0] = GameOfLife.Alive; | |
GameOfLife.LWSShip[1][1] = GameOfLife.Dead; | |
GameOfLife.LWSShip[1][2] = GameOfLife.Dead; | |
GameOfLife.LWSShip[1][3] = GameOfLife.Alive; | |
GameOfLife.LWSShip[2]= new Array(); | |
GameOfLife.LWSShip[2][0] = GameOfLife.Dead; | |
GameOfLife.LWSShip[2][1] = GameOfLife.Dead; | |
GameOfLife.LWSShip[2][2] = GameOfLife.Dead; | |
GameOfLife.LWSShip[2][3] = GameOfLife.Alive; | |
GameOfLife.LWSShip[3]= new Array(); | |
GameOfLife.LWSShip[3][0] = GameOfLife.Dead; | |
GameOfLife.LWSShip[3][1] = GameOfLife.Dead; | |
GameOfLife.LWSShip[3][2] = GameOfLife.Dead; | |
GameOfLife.LWSShip[3][3] = GameOfLife.Alive; | |
GameOfLife.LWSShip[4]= new Array(); | |
GameOfLife.LWSShip[4][0] = GameOfLife.Alive; | |
GameOfLife.LWSShip[4][1] = GameOfLife.Dead; | |
GameOfLife.LWSShip[4][2] = GameOfLife.Alive; | |
GameOfLife.LWSShip[4][3] = GameOfLife.Dead; | |
var Config = {}; | |
Config.CellSize = 2; | |
Config.Height = 200; | |
Config.Width = 700; | |
Config.GridColor = "#000"; | |
Config.LiveColor = "red"; | |
Config.DeadColor = "#000" | |
Config.RowCount = Config.Height / Config.CellSize; | |
Config.ColCount = Config.Width / Config.CellSize; | |
var c = document.getElementById('c'), | |
ctx = c.getContext('2d'), | |
grid; | |
GameOfLife.placeFigure = function (fig, x, y) { | |
for (i = 0; i < fig.length; i++) { | |
for (j = 0; j < fig.length; j++) { | |
grid[x + i][y + j] = fig[i][j]; | |
} | |
} | |
} | |
GameOfLife.transposeFigure = function (fig) { | |
var newfig = new Array(); | |
for (i = 0; i < fig[0].length; i++) { | |
newfig[i] = new Array(); | |
for (j = 0; j < fig.length; j++) { | |
newfig[i][j] = fig[j][i]; | |
} | |
} | |
return newfig; | |
} | |
init = function () { | |
grid = initGrid(); | |
//GameOfLife.placeFigure(GameOfLife.glider, 0, 0); | |
//GameOfLife.placeFigure(GameOfLife.transposeFigure(GameOfLife.glider), 15, 15); | |
//GameOfLife.placeFigure(GameOfLife.glider, 15, 0); | |
//GameOfLife.placeFigure(GameOfLife.transposeFigure(GameOfLife.glider), 25, 0); | |
//GameOfLife.placeFigure(GameOfLife.LWSShip, 100, 30); | |
GameOfLife.placeFigure((GameOfLife.LWSShip), 100, 10); | |
initCanvas(); | |
renderGrid(); | |
animloop(); | |
} | |
getPointCell = function (x, y) { | |
return grid[x][y]; | |
} | |
initCanvas = function () { | |
c.width = Config.Width + 1; | |
c.height = Config.Height + 1; | |
c.addEventListener('mousedown', startpaint, false); | |
c.addEventListener('mousemove', paint, false); | |
c.addEventListener('mouseup', stoppaint, false); | |
ctx.strokeStyle = Config.GridColor; | |
ctx.fillStyle = Config.GridColor; | |
ctx.lineWidth = 1; | |
ctx.fillRect(0, 0, Config.Width, Config.Height); | |
} | |
var paintStarted = false; | |
function startpaint(ev) { | |
paintStarted = true; | |
} | |
function stoppaint(ev) { | |
paintStarted = false; | |
} | |
function paint(ev) { | |
if (paintStarted) { | |
if (ev.layerX || ev.layerX == 0) { // Firefox | |
ev._x = ev.layerX; | |
ev._y = ev.layerY; | |
} else if (ev.offsetX || ev.offsetX == 0) { // Opera | |
ev._x = ev.offsetX; | |
ev._y = ev.offsetY; | |
} | |
currentDiff[currentDiff.length] = { | |
x: (ev._x - ev._x % Config.CellSize) / Config.CellSize, | |
y: (ev._y - ev._y % Config.CellSize) / Config.CellSize | |
}; | |
grid[(ev._x - ev._x % Config.CellSize) / Config.CellSize][(ev._y - ev._y % Config.CellSize) / Config.CellSize] = (grid[(ev._x - ev._x % Config.CellSize) / Config.CellSize][(ev._y - ev._y % Config.CellSize) / Config.CellSize] + 1) % 2; | |
} | |
} | |
var countNeighbors = function (x, y) { | |
var count = 0; | |
for (var i = Math.max(0, x - 1); i <= Math.min(x + 1, Config.ColCount); ++i) { | |
for (var j = Math.max(0, y - 1); j <= Math.min(y + 1, Config.RowCount); ++j) { | |
if (i == x && j == y) continue; | |
count += grid[i][j]; | |
} | |
} | |
return count; | |
} | |
var currentDiff; | |
var newState = function () { | |
currentDiff = new Array(); | |
var changes = 0; | |
var newGrid = new Array(); | |
for (i = 0; i < grid.length; i++) { | |
newGrid[i] = new Array(); | |
for (j = 0; j < grid[i].length; j++) { | |
var neighbors = countNeighbors(i, j); | |
newGrid[i][j] = grid[i][j]; | |
if (grid[i][j] == GameOfLife.Alive) { | |
if (neighbors < 2 || neighbors > 3) { | |
newGrid[i][j] = GameOfLife.Dead; | |
currentDiff[changes] = { | |
x: i, | |
y: j | |
}; | |
changes++; | |
} | |
} else { | |
if (neighbors == 3) { | |
newGrid[i][j] = GameOfLife.Alive; | |
currentDiff[changes] = { | |
x: i, | |
y: j | |
}; | |
changes++; | |
} | |
} | |
} | |
} | |
grid = newGrid; | |
} | |
var initGrid = function () { | |
var grid = new Array(Math.round(Config.Width / Config.CellSize) + 1); | |
for (i = 0; i < grid.length; i++) { | |
grid[i] = new Array(Math.round(Config.Height / Config.CellSize) + 1); | |
for (j = 0; j < grid[i].length; j++) { | |
grid[i][j] = GameOfLife.Dead; //Init all Dead. | |
} | |
} | |
return grid; | |
} | |
var renderGrid = function () { | |
for (var i = 0; i * Config.CellSize < Config.Width; i++) { | |
for (var j = 0; j * Config.CellSize < Config.Height; j++) { | |
if (getPointCell(i, j) == GameOfLife.Alive) { | |
ctx.fillStyle = Config.LiveColor; | |
} else { | |
ctx.fillStyle = Config.DeadColor; | |
} | |
ctx.fillRect(i * Config.CellSize, j * Config.CellSize, Config.CellSize - 1, Config.CellSize - 1); | |
} | |
} | |
}; | |
var renderDiff = function () { | |
for (var i = 0; i < currentDiff.length; i++) { | |
if (getPointCell(currentDiff[i].x, currentDiff[i].y) == GameOfLife.Alive) { | |
ctx.fillStyle = Config.LiveColor; | |
} else { | |
ctx.fillStyle = Config.DeadColor; | |
} | |
ctx.fillRect(currentDiff[i].x * Config.CellSize, currentDiff[i].y * Config.CellSize, Config.CellSize - 1, Config.CellSize - 1); | |
} | |
}; | |
var render = function () { | |
renderDiff(); | |
}; | |
function animloop() { | |
requestAnimationFrame(animloop, c); | |
if (!paintStarted) { | |
newState(); | |
} | |
render(); | |
// | |
//sleep(1000); | |
//newState(); | |
} | |
function sleep(milliseconds) { | |
var start = new Date().getTime(); | |
for (var i = 0; i < 1e7; i++) { | |
if ((new Date().getTime() - start) > milliseconds) { | |
break; | |
} | |
} | |
} | |
init() | |
}); |
This file contains hidden or 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
body { | |
background: #080808; | |
} | |
canvas { | |
display: block; | |
left: 50%; | |
margin: -150px 0 0 -350px; | |
position: absolute; | |
top: 50%; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment