From 38acbf861e391fafdc070a7c1aedae1e9864ab4f Mon Sep 17 00:00:00 2001 From: Justin Young Date: Mon, 17 Jun 2024 10:12:39 -0400 Subject: [PATCH] added ui controls --- src/CA.ts | 40 ++++++++++++++++--- src/ui.ts | 117 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 142 insertions(+), 15 deletions(-) diff --git a/src/CA.ts b/src/CA.ts index 4c5fbf2..b28b4ac 100644 --- a/src/CA.ts +++ b/src/CA.ts @@ -1,17 +1,29 @@ -export function applyCellularAutomataRules(map: number[], width: number, height: number): number[] { +export function applyCellularAutomataRules( + map: number[], + width: number, + height: number, + oob: string | undefined, + cutoff0: number | undefined, + cutoff1: number | undefined +): number[] { const newMap = new Array(width * height).fill(0); + let zeroLimit = 4; + if (cutoff0) zeroLimit = cutoff0 + 1; + let oneLimit = 5; + if (cutoff1) oneLimit = cutoff1; + for (let i = 0; i < height * width; i++) { for (let x = 0; x < width; x++) { - const wallCount = countAdjacentWalls(map, width, height, i); + const wallCount = countAdjacentWalls(map, width, height, i, oob); if (map[i] === 1) { - if (wallCount < 4) { + if (wallCount < zeroLimit) { newMap[i] = 0; // Change to floor if there are less than 4 adjacent walls } else { newMap[i] = 1; // Remain wall } } else { - if (wallCount >= 5) { + if (wallCount >= oneLimit) { newMap[i] = 1; // Change to wall if there are 5 or more adjacent walls } else { newMap[i] = 0; // Remain floor @@ -22,7 +34,7 @@ export function applyCellularAutomataRules(map: number[], width: number, height: return newMap; } -function countAdjacentWalls(map: number[], width: number, height: number, index: number): number { +function countAdjacentWalls(map: number[], width: number, height: number, index: number, oob: string | undefined): number { let count = 0; const y = Math.floor(index / width); @@ -39,7 +51,23 @@ function countAdjacentWalls(map: number[], width: number, height: number, index: const adjacentIndex = newY * width + newX; if (map[adjacentIndex] === 1) count++; } else { - count++; // Perceive out of bounds as wall + switch (oob) { + case "floor": + break; + case "wall": + count++; + break; + case "random": + let coinflip = Math.random(); + if (coinflip > 0.5) count++; + break; + case "mirror": + if (i == 0 || j == 0) count++; + break; + default: + count++; // Perceive out of bounds as wall + break; + } } } } diff --git a/src/ui.ts b/src/ui.ts index 844138f..b9081d0 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -6,16 +6,25 @@ export const bluey = new Rectangle({ width: 16, height: 16, color: Color.fromRGB export const whitey = new Rectangle({ width: 16, height: 16, color: Color.fromRGB(255, 255, 255, 1) }); export const model = { + OOBbehavior: undefined as HTMLSelectElement | undefined, + cutoff0: undefined as HTMLInputElement | undefined, + cutoff1: undefined as HTMLInputElement | undefined, resetSim: (_e: any, m: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any m.tiles = Array(1296).fill(0); getNewNoiseField(); drawTilemap(); + if (m.OOBbehavior) m.OOBbehavior.value = "wall"; + if (m.cutoff0) m.cutoff0.value = "3"; + if (m.cutoff1) m.cutoff1.value = "5"; }, runSim: (_e: any, m: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any - m.tiles = applyCellularAutomataRules(m.tiles, 36, 36); + const oob = m.OOBbehavior?.value; + const cutoff0 = parseInt(m.cutoff0?.value); + const cutoff1 = parseInt(m.cutoff1?.value); + m.tiles = applyCellularAutomataRules(m.tiles, 36, 36, oob, cutoff0, cutoff1); redrawTilemap(m.tiles, tmap, game); }, tiles: Array(1296).fill(0), @@ -29,21 +38,111 @@ export const template = ` width: 100vw; height: 100vh; } - div{ - display: flex; - flex-direction: column; + hud-layer{ + position: absolute; + top: 0; + left: 0; width: 100%; height: 100%; + display: flex; + flex-direction: column; justify-content: center; align-items: center; - gap: 5px; } + .app{ + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + .button{ + padding: 5px; + margin: 5px; + border-radius: 5px; + background-color: #ccc; + border: 1px solid #000; + cursor: pointer; + font-size: 24px; + color: #0000ff; + + } + + .controls{ + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 10%; + display: flex; + justify-content: center; + align-items: center; + gap: 10px; + color: #0000ff; + font-size: 24px; + + } + + select { + padding: 5px; + margin: 5px; + border-radius: 5px; + background-color: #ccc; + color: #0000ff; + } + + input { + padding: 5px; + margin: 5px; + border-radius: 5px; + background-color: #ccc; + color: #0000ff; + font-size: 16px; + text-align: center; + } + + .buttoncontainer{ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 10%; + display: flex; + justify-content: center; + align-items: center; + } + -
- - - +
+
+ + +
+ + +
+ +
+ + + + cutoff0} /> + + cutoff1} /> +
+ + + +
+
`; function redrawTilemap(map: number[], tilemap: TileMap, game: Engine) {