Skip to content

Commit c6b4876

Browse files
committed
add interactivity
1 parent b170bc9 commit c6b4876

File tree

6 files changed

+91
-25
lines changed

6 files changed

+91
-25
lines changed

05-game-of-life/Cargo.toml

+6-5
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ wee_alloc = { version = "0.4.5", optional = true }
3333
[dev-dependencies]
3434
wasm-bindgen-test = "0.3.13"
3535

36-
[dependencies.web-sys]
37-
version = "0.3"
38-
features = [
39-
"console",
40-
]
36+
# logging
37+
# [dependencies.web-sys]
38+
# version = "0.3"
39+
# features = [
40+
# "console",
41+
# ]
4142

4243
[profile.release]
4344
# Tell `rustc` to optimize for small code size.

05-game-of-life/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ A zero-player game to learn how to use Rust, WebAssembly, and JavaScript togethe
1313
- implementing the Game of Life with Rust.
1414
- rendering to canvas directly from memory with JavaScript.
1515
- testing the tick function and debugging.
16+
- pausing and resuming the game.
17+
- toggling a cell's state on click.
1618

1719
Based on [The Rust and WebAssembly Book](https://rustwasm.github.io/docs/book/) by The Rust and WebAssembly Working Group (2021).

05-game-of-life/src/lib.rs

+28-14
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ mod utils;
33
use std::fmt;
44
use wasm_bindgen::prelude::*;
55
extern crate js_sys;
6-
extern crate web_sys;
6+
// extern crate web_sys;
77

88
// A macro to provide `println!(..)`-style syntax for `console.log` logging.
9-
macro_rules! log {
10-
($( $t:tt)* ) => {
11-
web_sys::console::log_1(&format!( $( $t )*).into());
12-
};
13-
}
9+
// macro_rules! log {
10+
// ($( $t:tt)* ) => {
11+
// web_sys::console::log_1(&format!( $( $t )*).into());
12+
// };
13+
// }
1414

1515
#[wasm_bindgen]
1616
#[repr(u8)]
@@ -20,6 +20,15 @@ pub enum Cell {
2020
Alive = 1,
2121
}
2222

23+
impl Cell {
24+
fn toggle(&mut self) {
25+
*self = match *self {
26+
Cell::Dead => Cell::Alive,
27+
Cell::Alive => Cell::Dead,
28+
}
29+
}
30+
}
31+
2332
#[wasm_bindgen]
2433
pub struct Universe {
2534
width: u32,
@@ -74,13 +83,13 @@ impl Universe {
7483
let cell = self.cells[idx];
7584
let live_neighbors = self.live_neighbor_count(row, col);
7685

77-
log!(
78-
"cell[{}, {}] is initially {:?} and has {} live neighbors",
79-
row,
80-
col,
81-
cell,
82-
live_neighbors
83-
);
86+
// log!(
87+
// "cell[{}, {}] is initially {:?} and has {} live neighbors",
88+
// row,
89+
// col,
90+
// cell,
91+
// live_neighbors
92+
// );
8493

8594
let next_cell = match (cell, live_neighbors) {
8695
// Rule 1: Any live cell with fewer than two live neighbours
@@ -99,7 +108,7 @@ impl Universe {
99108
(otherwise, _) => otherwise,
100109
};
101110

102-
log!("it becomes {:?}", next_cell);
111+
// log!("it becomes {:?}", next_cell);
103112

104113
next[idx] = next_cell;
105114
}
@@ -160,6 +169,11 @@ impl Universe {
160169
self.height = height;
161170
self.cells = (0..self.width * height).map(|_i| Cell::Dead).collect();
162171
}
172+
173+
pub fn toggle_cell(&mut self, row: u32, col: u32) {
174+
let idx = self.get_index(row, col);
175+
self.cells[idx].toggle();
176+
}
163177
}
164178

165179
impl fmt::Display for Universe {

05-game-of-life/www/index.html

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<meta charset="utf-8">
4+
<meta charset="utf-8" />
55
<title>Game of Life</title>
66
<style>
77
body {
@@ -18,7 +18,11 @@
1818
</style>
1919
</head>
2020
<body>
21-
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
21+
<noscript
22+
>This page contains webassembly and javascript content, please enable
23+
javascript in your browser.</noscript
24+
>
25+
<button id="play-pause"></button>
2226
<canvas id="game-of-life-canvas"></canvas>
2327
<script src="./bootstrap.js"></script>
2428
</body>

05-game-of-life/www/index.js

+47-4
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ canvas.width = (CELL_SIZE + 1) * width + 1;
3131

3232
const ctx = canvas.getContext("2d");
3333

34+
let animationId = null;
35+
3436
const renderLoop = () => {
35-
debugger;
36-
universe.tick();
37+
// debugger;
3738
drawGrid();
3839
drawCells();
39-
requestAnimationFrame(renderLoop);
40+
universe.tick();
41+
animationId = requestAnimationFrame(renderLoop);
4042
};
4143

4244
const drawGrid = () => {
@@ -79,6 +81,47 @@ const drawCells = () => {
7981
ctx.stroke();
8082
};
8183

84+
// Pausing and Resuming the Game
85+
const isPaused = () => animationId === null;
86+
87+
const playPauseButton = document.getElementById("play-pause");
88+
89+
const play = () => {
90+
playPauseButton.textContent = "⏸";
91+
renderLoop();
92+
};
93+
94+
const pause = () => {
95+
playPauseButton.textContent = "▶";
96+
cancelAnimationFrame(animationId);
97+
animationId = null;
98+
};
99+
100+
playPauseButton.addEventListener("click", (event) =>
101+
isPaused() ? play() : pause()
102+
);
103+
104+
// Toggling a Cell's State on "click" Events
105+
canvas.addEventListener("click", (event) => {
106+
const boundingRect = canvas.getBoundingClientRect();
107+
108+
const scaleX = canvas.width / boundingRect.width;
109+
const scaleY = canvas.height / boundingRect.height;
110+
111+
const canvasLeft = (event.clientX - boundingRect.left) * scaleX;
112+
const canvasTop = (event.clientY - boundingRect.top) * scaleY;
113+
114+
const row = Math.min(Math.floor(canvasTop / (CELL_SIZE + 1), height - 1));
115+
const col = Math.min(Math.floor(canvasLeft / (CELL_SIZE + 1), width - 1));
116+
117+
universe.toggle_cell(row, col);
118+
119+
drawGrid();
120+
drawCells();
121+
});
122+
123+
// Init
82124
drawGrid();
83125
drawCells();
84-
requestAnimationFrame(renderLoop);
126+
// requestAnimationFrame(renderLoop);
127+
play();

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,7 @@ A zero-player game to learn how to use Rust, WebAssembly, and JavaScript togethe
104104
- implementing the Game of Life with Rust.
105105
- rendering to canvas directly from memory with JavaScript.
106106
- testing the tick function and debugging.
107+
- pausing and resuming the game.
108+
- toggling a cell's state on click.
107109

108110
Based on [The Rust and WebAssembly Book](https://rustwasm.github.io/docs/book/) by The Rust and WebAssembly Working Group (2021).

0 commit comments

Comments
 (0)