Skip to content

Commit

Permalink
Universe now fills all available screen space
Browse files Browse the repository at this point in the history
Also adds a reset button to re-seed the universe.
  • Loading branch information
chrisnewtn committed Jan 25, 2025
1 parent e3fadbc commit fedfdeb
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 40 deletions.
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<section class="buttons">
<button id="play-pause">pause</button>
<button id="clear">clear</button>
<button id="reset">reset</button>
</section>
<footer>
<a target="_blank" href="https://github.com/chrisnewtn/wasm-game-of-life">view source</a>
Expand Down
73 changes: 43 additions & 30 deletions public/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,51 @@ const GRID_COLOR = "#ccc";
const DEAD_COLOR = "#000";
const ALIVE_COLOR = "#fff";

const width = universe.width();
const height = universe.height();
let uWidth = universe.width();
let uHeight = universe.height();

/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('game-of-life-canvas');

let cellSize;
const cellSize = 5;

const setCanvasDimensions = () => {
cellSize = Math.floor(
Math.min(
document.documentElement.clientHeight,
document.documentElement.clientWidth
) / 64
);
const setUniverseDimensions = () => {
const {width: w, height: h} = canvas.getBoundingClientRect();

canvas.height = (cellSize + CELL_BORDER) * height + CELL_BORDER;
canvas.width = (cellSize + CELL_BORDER) * width + CELL_BORDER;
};
const width = Math.floor(Math.max(w, window.innerWidth));
const height = Math.floor(h);

window.addEventListener('resize', () => {
setCanvasDimensions();
});
const blockSize = 8;

const blocksWide = Math.floor(width / cellSize / blockSize);
const blocksHigh = Math.floor(height / cellSize / blockSize);

uWidth = blockSize * blocksWide;
uHeight = blockSize * blocksHigh;

universe.resize_and_seed(uWidth, uHeight);

canvas.width = uWidth * cellSize;
canvas.height = uHeight * cellSize;
};

setCanvasDimensions();
window.addEventListener('resize', setUniverseDimensions);
setUniverseDimensions();

const ctx = canvas.getContext('2d');

const drawGrid = () => {
ctx.beginPath();
ctx.strokeStyle = GRID_COLOR;

for (let i = 0; i <= width; i++) {
for (let i = 0; i <= uWidth; i++) {
ctx.moveTo(i * (cellSize + CELL_BORDER) + CELL_BORDER, 0);
ctx.lineTo(i * (cellSize + CELL_BORDER) + CELL_BORDER, (cellSize + CELL_BORDER) * height + CELL_BORDER);
ctx.lineTo(i * (cellSize + CELL_BORDER) + CELL_BORDER, (cellSize + CELL_BORDER) * uHeight + CELL_BORDER);
}

for (let j = 0; j <= height; j++) {
for (let j = 0; j <= uHeight; j++) {
ctx.moveTo(0, j * (cellSize + CELL_BORDER) + CELL_BORDER);
ctx.lineTo((cellSize + CELL_BORDER) * width + CELL_BORDER, j * (cellSize + CELL_BORDER) + CELL_BORDER);
ctx.lineTo((cellSize + CELL_BORDER) * uWidth + CELL_BORDER, j * (cellSize + CELL_BORDER) + CELL_BORDER);
}

ctx.stroke();
Expand All @@ -59,17 +64,17 @@ const drawGrid = () => {
* @param {number} column
*/
const getIndex = (row, column) => {
return row * width + column;
return row * uWidth + column;
};

const drawCells = () => {
const cellsPtr = universe.cells();
const cells = new Uint8Array(memory.buffer, cellsPtr, width * height);
const cells = new Uint8Array(memory.buffer, cellsPtr, uWidth * uHeight);

ctx.beginPath();

for (let row = 0; row < height; row++) {
for (let col = 0; col < width; col++) {
for (let row = 0; row < uHeight; row++) {
for (let col = 0; col < uWidth; col++) {
const idx = getIndex(row, col);

ctx.fillStyle = cells[idx] === Cell.Dead
Expand Down Expand Up @@ -160,8 +165,8 @@ function screenCoordToCanvasCoord(x, y) {
const canvasLeft = (x - boundingRect.left) * scaleX;
const canvasTop = (y - boundingRect.top) * scaleY;

const row = Math.min(Math.floor(canvasTop / (cellSize + CELL_BORDER)), height - CELL_BORDER);
const col = Math.min(Math.floor(canvasLeft / (cellSize + CELL_BORDER)), width - CELL_BORDER);
const row = Math.min(Math.floor(canvasTop / (cellSize + CELL_BORDER)), uHeight - CELL_BORDER);
const col = Math.min(Math.floor(canvasLeft / (cellSize + CELL_BORDER)), uWidth - CELL_BORDER);

return {row, col};
}
Expand All @@ -182,7 +187,7 @@ function paintCircle(touch) {
const mouseToToggle = e => {
const {row, col} = clientCoordToRowCol(e);

if (e.ctrlKey && col < width - 1 && row < width - 1) {
if (e.ctrlKey && col < uWidth - 1 && row < uWidth - 1) {
paintGlider(row, col);
} else {
paintCell(row, col);
Expand Down Expand Up @@ -218,7 +223,15 @@ const clearButton = document.getElementById('clear');

clearButton.addEventListener('click', e => {
e.preventDefault();
universe.set_height(height);
universe.set_width(width);
universe.set_height(uHeight);
universe.set_width(uWidth);
drawCells();
});

const resetButton = document.getElementById('reset');

resetButton.addEventListener('click', e => {
e.preventDefault();
universe.resize_and_seed(uWidth, uHeight);
drawCells();
});
4 changes: 3 additions & 1 deletion public/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ html, body {
body {
display: grid;
place-content: center;
grid-template-rows: min-content auto min-content;
grid-template-rows: auto min-content min-content;
gap: 1rem;
align-content: stretch;
}
canvas {
cursor: crosshair;
align-self: stretch;
max-width: 100%;
}
.buttons {
display: flex;
Expand Down
32 changes: 23 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ pub struct Universe {
cells: Vec<Cell>,
}

fn generate_cells(width: u32, height: u32) -> Vec<Cell> {
(0..width * height)
.map(|i| {
if i % 2 == 0 || i % 7 == 0 {
Cell::Alive
} else {
Cell::Dead
}
})
.collect()
}

#[wasm_bindgen]
impl Universe {
pub fn new() -> Universe {
Expand All @@ -44,15 +56,7 @@ impl Universe {
let width = 64;
let height = 64;

let cells = (0..width * height)
.map(|i| {
if i % 2 == 0 || i % 7 == 0 {
Cell::Alive
} else {
Cell::Dead
}
})
.collect();
let cells = generate_cells(width, height);

Universe {
width,
Expand Down Expand Up @@ -87,6 +91,16 @@ impl Universe {
self.cells = (0..self.width * height).map(|_| Cell::Dead).collect();
}

pub fn seed_cells(&mut self) {
self.cells = generate_cells(self.width, self.height);
}

pub fn resize_and_seed(&mut self, width: u32, height: u32) {
self.width = width;
self.height = height;
self.seed_cells();
}

pub fn toggle_cell(&mut self, row: u32, column: u32) {
let idx = self.get_index(row, column);
self.cells[idx].toggle();
Expand Down

0 comments on commit fedfdeb

Please sign in to comment.