Created
April 6, 2015 15:25
-
-
Save AlexandruSimandi/1f5bb5b37b77c608632f to your computer and use it in GitHub Desktop.
game of life javascript with 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
var UIModule = (function (){ | |
//function for listener, starts/stops runnig game | |
function enterPressed(e){ | |
if(e.keyCode == 13){ | |
if(gameModule.isRunning() == false){ | |
document.getElementById('status').innerHTML = "Game is running "; | |
gameModule.run(); | |
}else { | |
document.getElementById('status').innerHTML = "Game is paused "; | |
gameModule.pause(); | |
} | |
} | |
} | |
//makes possible to click a cell anytime and change alive/dead property | |
function clickCell(e){ | |
var mousePos = getMousePos(e); | |
var i = parseInt(mousePos.x / gameModule.getCellDiameter()); | |
var j = parseInt(mousePos.y / gameModule.getCellDiameter()); | |
gameModule.drawCell(i,j); | |
} | |
//gets mouse position relative to canvas, returns x,y coordiantes | |
function getMousePos(evt) { | |
var rect = gameModule.getCanvas().getBoundingClientRect(); | |
return { | |
x: evt.clientX - rect.left, | |
y: evt.clientY - rect.top | |
}; | |
} | |
return { | |
initialize: function(){ | |
window.addEventListener("keydown",enterPressed,false); | |
document.getElementById("Acorn").addEventListener("mousedown",gameModule.makeAcorn,false); | |
gameModule.getCanvas().addEventListener("mousedown",clickCell,false); | |
} | |
}; | |
})(); | |
//module used to compute and render in canvas | |
var gameModule = (function () { | |
//matrix size | |
var dimension; | |
//canvas used in html file | |
var canvas; | |
//basic cell stuff good to know for module | |
var cellMargin; | |
var cellDiameter; | |
//canvas prop | |
var canvasDraw; | |
var canvasWidth; | |
var canvasHeight; | |
//matrix for alive/dead cells and matrix to memorize changes | |
var world; | |
var changes; | |
var moduleInitialized = false; | |
var gameRunning; | |
//draws cell in canvas | |
function drawCell(x,y,radius,alive){ | |
//canvasDraw.clearRect(x,y,radius,radius); | |
canvasDraw.beginPath(); | |
canvasDraw.fillStyle = "#000000"; | |
//canvasDraw.arc(x,y,radius,0,2*Math.PI); | |
canvasDraw.rect(x,y,radius,radius); | |
canvasDraw.closePath(); | |
canvasDraw.stroke(); | |
if(alive){ | |
canvasDraw.fillStyle="green"; | |
} else canvasDraw.fillStyle="white"; | |
canvasDraw.fill(); | |
} | |
//gets the cell properly in case the questioned cell is over the border | |
function getCell(x, y){ | |
if(x>=dimension) { x = 0; } | |
if(y>=dimension) { y = 0; } | |
if(x < 0) { x = dimension - 1; } | |
if(y < 0) { y = dimension - 1; } | |
return world[x][y]; | |
} | |
//counts how many alive neighbors there are | |
function checkNeighbours(x,y){ | |
var count = 0; | |
if(getCell(x-1, y-1)) count ++; | |
if(getCell(x, y-1)) count ++; | |
if(getCell(x+1, y-1)) count ++; | |
if(getCell(x-1, y)) count ++; | |
if(getCell(x+1, y)) count ++; | |
if(getCell(x-1, y+1)) count ++; | |
if(getCell(x, y+1)) count ++; | |
if(getCell(x+1, y+1)) count ++; | |
return count; | |
} | |
//todo, paint only changes | |
function paintCanvas(){ | |
for(var i = 0; i < dimension; i++){ | |
for(var j = 0; j < dimension; j++){ | |
if(changes[i][j]) | |
drawCell(i*cellDiameter+1,j*cellDiameter+1,cellDiameter,world[i][j]); | |
} | |
} | |
} | |
//places "acorn" shape on screen | |
function makeAcorn() { | |
var middle = parseInt(dimension/2); | |
world[middle][middle] = true; | |
drawCell((middle)*cellDiameter+1,(middle)*cellDiameter+1,cellDiameter,world[middle][middle]); | |
world[middle + 1][middle] = true; | |
drawCell((middle + 1)*cellDiameter+1,(middle)*cellDiameter+1,cellDiameter,world[middle + 1][middle]); | |
world[middle + 1][middle - 1] = true; | |
drawCell((middle + 1)*cellDiameter+1,(middle - 1)*cellDiameter+1,cellDiameter,world[middle + 1][middle - 1]); | |
world[middle + 2][middle] = true; | |
drawCell((middle + 2)*cellDiameter+1,(middle)*cellDiameter+1,cellDiameter,world[middle + 2][middle]); | |
world[middle + 2][middle + 1] = true; | |
drawCell((middle + 2)*cellDiameter+1,(middle + 1)*cellDiameter+1,cellDiameter,world[middle + 2][middle + 1]); | |
}; | |
//looping function that computes and renders next generation in game, stops/stars running based on bool gameRunning modified by enterPressed | |
function playGeneration(){ | |
if(gameRunning){ | |
var worldTemp = []; | |
for(var i = 0; i < dimension; i++){ | |
worldTemp[i] = []; | |
var lifeScore; | |
for(var j = 0; j < dimension; j++){ | |
lifeScore = checkNeighbours(i,j); | |
if (world[i][j]) { | |
if(lifeScore == 2 || lifeScore == 3) { | |
worldTemp[i][j] = true; | |
} else { | |
worldTemp[i][j] = false; | |
} | |
} else if(lifeScore == 3) { | |
worldTemp[i][j] = true; | |
} | |
if(world[i][j] != worldTemp[i][j]){ | |
changes[i][j] = true; | |
} else changes[i][j] = false; | |
} | |
} | |
world = worldTemp; | |
paintCanvas(); | |
var x = setTimeout(function() {playGeneration();}, 1); | |
} | |
} | |
return { | |
//initializes everything only once | |
initialize: function(){ | |
if(moduleInitialized == false){ | |
moduleInitialized = true; | |
dimension = parseInt(window.prompt("enter matrix size")); | |
canvas = document.getElementById("main"); | |
cellMargin = 0; | |
cellDiameter = canvas.width/(dimension + cellMargin); | |
canvasDraw = canvas.getContext("2d"); | |
canvasDraw.lineWidth = 0.5; | |
canvasWidth = canvas.width; | |
canvasHeight = canvas.height; | |
world = []; | |
changes = []; | |
for(var i = 0; i < dimension; i++){ | |
world[i] = []; | |
changes[i] = []; | |
for(var j = 0; j < dimension; j++){ | |
world[i][j] = false; | |
changes[i][j] = true; | |
} | |
} | |
gameRunning = false; | |
//builds first time every cell | |
paintCanvas(); | |
} | |
}, | |
run: function (){ | |
gameRunning = true; | |
playGeneration(); | |
}, | |
pause: function(){ | |
gameRunning = false; | |
}, | |
isRunning: function(){ | |
return gameRunning; | |
}, | |
makeAcorn: function(){ | |
makeAcorn(); | |
}, | |
getCanvas: function(){ | |
return canvas; | |
}, | |
drawCell: function(i,j){ | |
if(world[i][j]){ | |
world[i][j] = false; | |
} else world[i][j] = true; | |
drawCell(i*cellDiameter+1,j*cellDiameter+1,cellDiameter,world[i][j]); | |
}, | |
getCanvas: function(){ | |
return canvas; | |
}, | |
getCellDiameter: function(){ | |
return cellDiameter; | |
} | |
}; | |
})(); | |
window.onload = function(){ | |
gameModule.initialize(); | |
UIModule.initialize(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment