add controls for clearing canvas and resetting to initial seed

This commit is contained in:
Sorrel Bri 2020-05-25 15:40:02 -07:00
parent fde2e26806
commit dbd671a964
6 changed files with 75 additions and 23 deletions

View file

@ -43,6 +43,9 @@ class CellStream extends Stream {
setLiving() { setLiving() {
this.head.setLiving(); this.head.setLiving();
} }
toggleLiving() {
this.head.toggleLiving();
}
} }
const cellStream = (living = false, liveNeighbors = 0) => { const cellStream = (living = false, liveNeighbors = 0) => {

View file

@ -7,6 +7,9 @@ const init = (gameField) => {
const rateEl = document.getElementById("rate"); const rateEl = document.getElementById("rate");
const forwardEl = document.getElementById("forward"); const forwardEl = document.getElementById("forward");
const playEl = document.getElementById("play"); const playEl = document.getElementById("play");
const resetEl = document.getElementById("reset");
const clearEl = document.getElementById("clear");
const canvasEl = document.getElementById("game-field");
const controls = { const controls = {
interval: null, interval: null,
play() { play() {
@ -19,14 +22,20 @@ const init = (gameField) => {
this.interval = null; this.interval = null;
} }
}, },
clear() {
gameField = gameField.clear();
},
reset() { reset() {
this.pause(); this.pause();
gameField.reset(); gameField = gameField.reset();
}, },
forward() { forward() {
gameField.advance(); gameField.advance();
}, },
rate: 10, rate: 10,
updateField(x, y) {
gameField = gameField.toggleCell(x, y);
},
updateRate(rate) { updateRate(rate) {
console.log("updating rate"); console.log("updating rate");
console.log(rate); console.log(rate);
@ -55,6 +64,20 @@ const init = (gameField) => {
controls.play(); controls.play();
forwardEl.disabled = true; forwardEl.disabled = true;
}); });
resetEl.addEventListener("click", (e) => {
e.preventDefault();
controls.reset();
});
clearEl.addEventListener("click", (e) => {
e.preventDefault();
controls.clear();
});
canvasEl.addEventListener("click", (e) => {
e.preventDefault();
if (controls.interval) return;
const { offsetX, offsetY } = e;
controls.updateField(offsetX, offsetY);
});
return controls; return controls;
}; };

View file

@ -5,44 +5,70 @@ const canvasEl = document.getElementById("game-field");
const canvas2D = canvasEl.getContext("2d"); const canvas2D = canvasEl.getContext("2d");
canvas2D.fillStyle = "white"; canvas2D.fillStyle = "white";
const parseSeed = (seed) => ({ const parseSeed = (seed) => {
fieldArray: [ if (seed && Array.isArray(seed)) {
[0, 1, 0], return {
[0, 0, 1], fieldArray: [
[1, 1, 1], [0, 1, 0],
], [0, 0, 1],
}); [1, 1, 1],
],
};
}
return seed;
};
const fieldView = (seed) => { const fieldView = (seed) => {
fieldArray = parseSeed(seed); console.log(seed);
seed = parseSeed(seed);
// generateTable(true); // generateTable(true);
const field = fieldStream(fieldArray); console.log(seed);
return { const field = fieldStream(seed);
const view = {
draw(x, y) { draw(x, y) {
const { scale, offset } = this.dimension; const { scale, offset } = this.dimension;
canvas2D.fillRect(x * scale + offset, y * scale + offset, scale, scale); canvas2D.fillRect(x * scale + offset, y * scale + offset, scale, scale);
}, },
dimension: { x0: 0, y0: 0, x1: 500, y1: 300, scale: 6, offset: 100 }, dimension: { x0: 0, y0: 0, x1: 500, y1: 300, scale: 6, offset: 100 },
field, field,
updateView(field) { updateView() {
canvas2D.clearRect(0, 0, this.dimension.x1, this.dimension.y1); canvas2D.clearRect(0, 0, this.dimension.x1, this.dimension.y1);
Object.entries(field.map) Object.entries(this.field.map)
.filter(([key, cell]) => cell.living) .filter(([key, cell]) => cell.living)
.map(([key]) => key.split(",")) .map(([key]) => key.split(","))
.forEach(([x, y]) => this.draw(x, y)); .forEach(([x, y]) => this.draw(x, y));
}, },
clear() {
return fieldView({});
},
reset() { reset() {
return fieldView(seed); const newField = fieldView(seed);
this.updateView(this.field); newField.updateView();
return newField;
}, },
advance() { advance() {
this.field = this.field.next.next; this.field = this.field.next.next;
this.updateView(this.field); this.updateView();
}, },
handleClick(e) { toggleCell(x, y) {
// toggle single cell const { scale, offset } = this.dimension;
x = Math.floor((x - offset) / scale);
y = Math.floor((y - offset) / scale);
console.log(x, y);
const fieldMap = Object.entries(this.field.map)
.map(([key, cell]) => [key, cell.living])
.reduce((map, [key, living]) => {
map[key] = [living];
return map;
}, {});
fieldMap[`${x},${y}`] = !!fieldMap[`${x},${y}`]
? [!fieldMap[`${x},${y}`][0]]
: [true];
return new fieldView({ fieldMap });
}, },
}; };
view.updateView();
return view;
}; };
module.exports = { module.exports = {

View file

@ -1,11 +1,11 @@
<div class="playControls"> <div class="playControls">
<button id="stop">⏹️</button> <button id="clear">⏹️</button>
<button id="reset">🔄️</button>
<button id="play">⏯️</button> <button id="play">⏯️</button>
<button id="forward">⏩️</button> <button id="forward">⏩️</button>
<input <input
type="range" type="range"
id="rate" id="rate"
onchange="controls.updateRoute"
min="1" min="1"
max="20" max="20"
value="10" value="10"

View file

@ -4,7 +4,7 @@ import css from "./styles/style.css";
const { fieldView } = require("./components/GameFieldTable"); const { fieldView } = require("./components/GameFieldTable");
const { init } = require("./components/Controls"); const { init } = require("./components/Controls");
(() => console.log("hello world!"))(); (() => console.log("hello world!"))();
window.game = fieldView(); window.game = fieldView([]);
window.controls = init(game); window.controls = init(game);
// controls // controls
// -- state=idle ? // -- state=idle ?

View file

@ -24,9 +24,9 @@ div.playControls {
border-radius: 1vh; border-radius: 1vh;
border: solid white .5vh; border: solid white .5vh;
grid-template-rows: 2fr 1fr; grid-template-rows: 2fr 1fr;
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 1vh; gap: 1vh;
grid-template-areas: "buttons buttons buttons" " slider slider slider"; grid-template-areas: "buttons buttons buttons buttons" "slider slider slider slider";
padding: 1vh; padding: 1vh;
} }