Skip to content

Commit d6cbdc9

Browse files
committed
add canvas and screenshot
1 parent 900932d commit d6cbdc9

File tree

7 files changed

+98
-11
lines changed

7 files changed

+98
-11
lines changed

05-game-of-life/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ default = ["console_error_panic_hook"]
1515

1616
[dependencies]
1717
wasm-bindgen = "0.2.63"
18+
js-sys = "0.3"
1819

1920
# The `console_error_panic_hook` crate provides better debugging of panics by
2021
# logging them with `console.error`. This is great for development, but requires

05-game-of-life/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
A zero-player game to learn how to use Rust, WebAssembly, and JavaScript together.
44

5+
<img src="screenshot.png">
6+
57
## Features
68

79
- cloning the project template and understanding the folder structure.
810
- building the project with wasm-pack.
911
- putting it into a web page with wasm-app.
1012
- serving locally with webpack.
1113
- implementing the Game of Life with Rust.
12-
- rendering with JavaScript.
14+
- rendering to canvas directly from memory with JavaScript.
1315

1416
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/screenshot.png

1.92 KB
Loading

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

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod utils;
22

33
use std::fmt;
44
use wasm_bindgen::prelude::*;
5+
extern crate js_sys;
56

67
#[wasm_bindgen]
78
#[repr(u8)]
@@ -79,8 +80,8 @@ impl Universe {
7980
let height = 64;
8081

8182
let cells = (0..width * height)
82-
.map(|i| {
83-
if i % 2 == 0 || i % 7 == 0 {
83+
.map(|_i| {
84+
if js_sys::Math::random() < 0.5 {
8485
Cell::Alive
8586
} else {
8687
Cell::Dead
@@ -98,6 +99,18 @@ impl Universe {
9899
pub fn render(&self) -> String {
99100
self.to_string()
100101
}
102+
103+
pub fn width(&self) -> u32 {
104+
self.width
105+
}
106+
107+
pub fn height(&self) -> u32 {
108+
self.height
109+
}
110+
111+
pub fn cells(&self) -> *const Cell {
112+
self.cells.as_ptr()
113+
}
101114
}
102115

103116
impl fmt::Display for Universe {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</head>
2020
<body>
2121
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
22-
<pre id="game-of-life-canvas"></pre>
22+
<canvas id="game-of-life-canvas"></canvas>
2323
<script src="./bootstrap.js"></script>
2424
</body>
2525
</html>

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

+71-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,78 @@
1-
import { Universe } from "game-of-life";
1+
import { memory } from 'game-of-life/game_of_life_bg';
2+
import { Universe, Cell } from "game-of-life";
23

3-
const pre = document.getElementById("game-of-life-canvas");
4+
// const pre = document.getElementById("game-of-life-canvas");
5+
// const universe = Universe.new();
6+
7+
// const renderLoop = () => {
8+
// pre.textContent = universe.render();
9+
// universe.tick();
10+
11+
// requestAnimationFrame(renderLoop);
12+
// };
13+
14+
// requestAnimationFrame(renderLoop);
15+
16+
const CELL_SIZE = 5; // px
17+
const GRID_COLOR = "#ccc";
18+
const DEAD_COLOR = "#fff";
19+
const ALIVE_COLOR = "#000";
20+
21+
// Construct the universe, and get its width and height.
422
const universe = Universe.new();
23+
const width = universe.width();
24+
const height = universe.height();
25+
26+
// Give the canvas room for all of our cells and a 1px border
27+
// around each of them.
28+
const canvas = document.getElementById("game-of-life-canvas");
29+
canvas.height = (CELL_SIZE + 1) * height + 1;
30+
canvas.width = (CELL_SIZE + 1) * width + 1;
31+
32+
const ctx = canvas.getContext('2d');
533

634
const renderLoop = () => {
7-
pre.textContent = universe.render();
835
universe.tick();
9-
36+
drawGrid();
37+
drawCells();
1038
requestAnimationFrame(renderLoop);
11-
};
39+
}
40+
41+
const drawGrid = () => {
42+
ctx.beginPath();
43+
ctx.strokeStyle = GRID_COLOR;
44+
45+
// Vertical lines
46+
for (let i = 0; i <= width; i++) {
47+
ctx.moveTo(i * (CELL_SIZE + 1) + 1, 0);
48+
ctx.lineTo(i * (CELL_SIZE + 1) + 1, (CELL_SIZE + 1) * height + 1);
49+
}
50+
51+
// Horizontal lines
52+
for (let j = 0; j <= height; j++) {
53+
ctx.moveTo(0, j* (CELL_SIZE + 1) + 1);
54+
ctx.lineTo((CELL_SIZE + 1) * width + 1, j* (CELL_SIZE + 1) + 1);
55+
}
56+
}
57+
58+
const getIndex = (row, column) => {
59+
return row * width + column;
60+
}
61+
62+
const drawCells = () => {
63+
const cellsPtr = universe.cells();
64+
const cells = new Uint8Array(memory.buffer, cellsPtr, width * height);
65+
ctx.beginPath();
66+
for (let row = 0; row < height; row ++) {
67+
for (let col = 0; col < width; col++) {
68+
const idx = getIndex(row, col);
69+
ctx.fillStyle = cells[idx] === Cell.Dead ? DEAD_COLOR : ALIVE_COLOR;
70+
ctx.fillRect(col * (CELL_SIZE + 1) + 1, row * (CELL_SIZE + 1) + 1, CELL_SIZE, CELL_SIZE);
71+
}
72+
}
73+
ctx.stroke();
74+
}
1275

13-
requestAnimationFrame(renderLoop);
76+
drawGrid();
77+
drawCells();
78+
requestAnimationFrame(renderLoop);

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,19 @@ A zero-player game to learn how to use Rust, WebAssembly, and JavaScript togethe
8989

9090
[See 05-game-of-life folder](https://github.com/solygambas/rust-projects/tree/main/05-game-of-life)
9191

92+
<p align="center">
93+
<a href="https://github.com/solygambas/rust-projects/tree/main/05-game-of-life">
94+
<img src="05-game-of-life/screenshot.png">
95+
</a>
96+
</p>
97+
9298
### Features
9399

94100
- cloning the project template and understanding the folder structure.
95101
- building the project with wasm-pack.
96102
- putting it into a web page with wasm-app.
97103
- serving locally with webpack.
98104
- implementing the Game of Life with Rust.
99-
- rendering with JavaScript.
105+
- rendering to canvas directly from memory with JavaScript.
100106

101107
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)