Last active
June 14, 2021 12:59
-
-
Save FlyInk13/2a2344ed26998dcbf99a66d9f5b0ccb0 to your computer and use it in GitHub Desktop.
Conway's Game of Life using vanilla JavaScript
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
let size = 20; | |
let border = 1; | |
let pause = true; | |
let sizeX = 0; | |
let sizeY = 0; | |
let cursor = [0, 0]; | |
let map = []; | |
let ctx; | |
function updateBlock(map, x, y) { | |
let cur = map[x][y]; | |
let sum = -cur; | |
for (let xi = -1; xi <= 1; xi++) { | |
for (let yi = -1; yi <= 1; yi++) { | |
const dx = ((x + xi) + sizeX) % sizeX; | |
const dy = ((y + yi) + sizeY) % sizeY; | |
sum += map[dx] ? map[dx][dy] : 0; | |
} | |
} | |
if (!cur && sum == 3) { | |
return 1; | |
} | |
if (cur && sum >= 2 && sum <= 3) { | |
return 1; | |
} | |
return 0; | |
} | |
function updateMap() { | |
map = map.map((line, x) => { | |
return line.map((value, y) => { | |
return updateBlock(map, x, y); | |
}); | |
}); | |
} | |
function getBlockColor(value) { | |
value = (1 - value) * 255; | |
return 'rgb(' + value + ', ' + value + ', ' + value + ')'; | |
} | |
function drawBlock(x, y, value) { | |
ctx.fillStyle = getBlockColor(value); | |
ctx.fillRect( | |
x * size + border, | |
y * size + border, | |
size - border * 2, | |
size - border * 2 | |
); | |
} | |
function drawCursor() { | |
const [x, y] = cursor; | |
const value = map[x][y]; | |
const cursorColor = !value ? 0.2 : 0.7; | |
drawBlock(x, y, cursorColor); | |
} | |
function drawScreen() { | |
map.forEach((line, x) => { | |
line.forEach((value, y) => { | |
drawBlock(x, y, value); | |
}); | |
}); | |
drawCursor(); | |
} | |
function eventLoop() { | |
if (!pause) { | |
updateMap(); | |
} | |
drawScreen(); | |
requestAnimationFrame(eventLoop); | |
} | |
function onKeyDown(event) { | |
pause = !pause; | |
} | |
function getMousePosition(event) { | |
const x = Math.floor(event.clientX / size); | |
const y = Math.floor(event.clientY / size); | |
return [x, y]; | |
} | |
function onMouseMove(event) { | |
const [x, y] = getMousePosition(event); | |
const [prevX, prevY] = cursor; | |
const cursorChanged = prevX != x || prevY != y; | |
if (!cursorChanged) { | |
return; | |
} | |
if (event.buttons) { | |
map[x][y] = !map[x][y]; | |
} | |
cursor = [x, y]; | |
} | |
function onMouseDown(event) { | |
const [x, y] = getMousePosition(event); | |
map[x][y] = !map[x][y]; | |
cursor = [x, y]; | |
} | |
function initMap() { | |
for (var x = 0; x < sizeX; x++) { | |
map[x] = []; | |
for (var y = 0; y < sizeY; y++) { | |
map[x][y] = 0; | |
} | |
} | |
} | |
function init() { | |
const canvas = document.createElement('canvas'); | |
document.body.style.margin = '0px'; | |
document.body.appendChild(canvas); | |
canvas.width = Math.floor(document.body.clientWidth / size) * size; | |
canvas.height = Math.floor(document.body.clientHeight / size) * size; | |
ctx = canvas.getContext('2d'); | |
ctx.fillStyle = getBlockColor(0.1); | |
ctx.fillRect(0, 0, canvas.width, canvas.height); | |
window.addEventListener('keydown', onKeyDown); | |
canvas.addEventListener('mousedown', onMouseDown); | |
canvas.addEventListener('mousemove', onMouseMove); | |
sizeX = Math.floor(canvas.width / size); | |
sizeY = Math.floor(canvas.height / size); | |
initMap(); | |
eventLoop(); | |
} | |
init(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment