From dbd671a964d747ed861f29c136f05f931687c21c Mon Sep 17 00:00:00 2001 From: Sorrel Bri Date: Mon, 25 May 2020 15:40:02 -0700 Subject: [PATCH] add controls for clearing canvas and resetting to initial seed --- src/components/Cell.js | 3 ++ src/components/Controls.js | 25 ++++++++++++- src/components/GameFieldTable.js | 60 +++++++++++++++++++++++--------- src/components/controls.html | 4 +-- src/index.js | 2 +- src/styles/contols.css | 4 +-- 6 files changed, 75 insertions(+), 23 deletions(-) diff --git a/src/components/Cell.js b/src/components/Cell.js index debd7cf..a1afaa6 100644 --- a/src/components/Cell.js +++ b/src/components/Cell.js @@ -43,6 +43,9 @@ class CellStream extends Stream { setLiving() { this.head.setLiving(); } + toggleLiving() { + this.head.toggleLiving(); + } } const cellStream = (living = false, liveNeighbors = 0) => { diff --git a/src/components/Controls.js b/src/components/Controls.js index aa02240..6495859 100644 --- a/src/components/Controls.js +++ b/src/components/Controls.js @@ -7,6 +7,9 @@ const init = (gameField) => { const rateEl = document.getElementById("rate"); const forwardEl = document.getElementById("forward"); const playEl = document.getElementById("play"); + const resetEl = document.getElementById("reset"); + const clearEl = document.getElementById("clear"); + const canvasEl = document.getElementById("game-field"); const controls = { interval: null, play() { @@ -19,14 +22,20 @@ const init = (gameField) => { this.interval = null; } }, + clear() { + gameField = gameField.clear(); + }, reset() { this.pause(); - gameField.reset(); + gameField = gameField.reset(); }, forward() { gameField.advance(); }, rate: 10, + updateField(x, y) { + gameField = gameField.toggleCell(x, y); + }, updateRate(rate) { console.log("updating rate"); console.log(rate); @@ -55,6 +64,20 @@ const init = (gameField) => { controls.play(); 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; }; diff --git a/src/components/GameFieldTable.js b/src/components/GameFieldTable.js index cf59002..d57b81e 100644 --- a/src/components/GameFieldTable.js +++ b/src/components/GameFieldTable.js @@ -5,44 +5,70 @@ const canvasEl = document.getElementById("game-field"); const canvas2D = canvasEl.getContext("2d"); canvas2D.fillStyle = "white"; -const parseSeed = (seed) => ({ - fieldArray: [ - [0, 1, 0], - [0, 0, 1], - [1, 1, 1], - ], -}); +const parseSeed = (seed) => { + if (seed && Array.isArray(seed)) { + return { + fieldArray: [ + [0, 1, 0], + [0, 0, 1], + [1, 1, 1], + ], + }; + } + return seed; +}; const fieldView = (seed) => { - fieldArray = parseSeed(seed); + console.log(seed); + seed = parseSeed(seed); // generateTable(true); - const field = fieldStream(fieldArray); - return { + console.log(seed); + const field = fieldStream(seed); + const view = { draw(x, y) { const { scale, offset } = this.dimension; canvas2D.fillRect(x * scale + offset, y * scale + offset, scale, scale); }, dimension: { x0: 0, y0: 0, x1: 500, y1: 300, scale: 6, offset: 100 }, field, - updateView(field) { + updateView() { canvas2D.clearRect(0, 0, this.dimension.x1, this.dimension.y1); - Object.entries(field.map) + Object.entries(this.field.map) .filter(([key, cell]) => cell.living) .map(([key]) => key.split(",")) .forEach(([x, y]) => this.draw(x, y)); }, + clear() { + return fieldView({}); + }, reset() { - return fieldView(seed); - this.updateView(this.field); + const newField = fieldView(seed); + newField.updateView(); + return newField; }, advance() { this.field = this.field.next.next; - this.updateView(this.field); + this.updateView(); }, - handleClick(e) { - // toggle single cell + toggleCell(x, y) { + 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 = { diff --git a/src/components/controls.html b/src/components/controls.html index 99ac0b8..382b908 100644 --- a/src/components/controls.html +++ b/src/components/controls.html @@ -1,11 +1,11 @@
- + + console.log("hello world!"))(); -window.game = fieldView(); +window.game = fieldView([]); window.controls = init(game); // controls // -- state=idle ? diff --git a/src/styles/contols.css b/src/styles/contols.css index ee5cdce..7256fef 100644 --- a/src/styles/contols.css +++ b/src/styles/contols.css @@ -24,9 +24,9 @@ div.playControls { border-radius: 1vh; border: solid white .5vh; grid-template-rows: 2fr 1fr; - grid-template-columns: 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr 1fr 1fr; gap: 1vh; - grid-template-areas: "buttons buttons buttons" " slider slider slider"; + grid-template-areas: "buttons buttons buttons buttons" "slider slider slider slider"; padding: 1vh; }