You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.2 KiB
JavaScript

import { Universe, Cell } from "wasm-game-of-life";
// Import wasm memory
import { memory } from "wasm-game-of-life/wasm_game_of_life_bg";
const CELL_SIZE = 5; // px
const GRID_COLOR = "#444444";
const DEAD_COLOR = "#000000";
const ALIVE_COLOR = "#FFFFFF";
const seed = Math.random();
const universe = ((seed) => {
if (seed < 1/3) return Universe.new_modulo();
else if (seed < 2/3) return Universe.new_random();
else return Universe.new_space_ship();
})(seed);
const width = universe.width();
const height = universe.height();
const canvas = document.getElementById("game-of-life-canvas");
canvas.height = (CELL_SIZE + 1) * height + 1;
canvas.width = (CELL_SIZE + 1) * width + 1;
const ctx = canvas.getContext('2d');
const PERIODE = 100; // ms
let start;
const renderLoop = (timestamp) => {
drawGrid();
drawCells();
if (start === undefined)
start = timestamp;
const elapsed = timestamp - start;
if (elapsed > PERIODE) {
universe.tick();
start = timestamp;
}
requestAnimationFrame(renderLoop);
};
const drawGrid = () => {
ctx.beginPath();
ctx.strokeStyle = GRID_COLOR;
for (let i = 0; i <= width; i++) {
ctx.moveTo(i * (CELL_SIZE + 1) + 1, 0);
ctx.lineTo(i * (CELL_SIZE + 1) + 1, (CELL_SIZE + 1) * height + 1);
}
for (let j = 0; j <= height; j++) {
ctx.moveTo(0, j * (CELL_SIZE + 1) + 1);
ctx.lineTo((CELL_SIZE + 1) * width + 1, j * (CELL_SIZE + 1) + 1);
}
ctx.stroke();
}
const getIndex = (row, column) => {
return row * width + column;
}
const drawCells = () => {
const cellsPtr = universe.cells();
const cells = new Uint8Array(memory.buffer, cellsPtr, width * height / 8);
ctx.beginPath();
for (let row = 0; row < height; row++) {
for (let col = 0; col < width; col++) {
const i = getIndex(row, col);
ctx.fillStyle = bitIsSet(i, cells)
? ALIVE_COLOR
: DEAD_COLOR;
ctx.fillRect(
col * (CELL_SIZE + 1) + 1,
row * (CELL_SIZE + 1) + 1,
CELL_SIZE,
CELL_SIZE
);
}
}
ctx.stroke();
}
const bitIsSet = (n, arr) => {
const byte = Math.floor(n / 8);
const mask = 1 << (n % 8);
return (arr[byte] & mask) === mask;
}
requestAnimationFrame(renderLoop);