|
3 | 3 | <head> |
4 | 4 | <meta charset="utf-8" /> |
5 | 5 | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
6 | | - <title>Perfect Maze — Always Solvable</title> |
| 6 | + <title>Maze Game v2</title> |
7 | 7 | <link rel="icon" type="image/x-icon" href="https://usrx215.github.io/scgames/mazegame.png"> |
8 | 8 | <style> |
9 | 9 | :root { --bg:#0b0e14; --panel:#11151f; --ink:#e6e6e6; --muted:#9aa4b2; --accent:#6ee7ff; --accent2:#a7f3d0; } |
|
18 | 18 | .controls button { cursor:pointer; transition: transform .05s ease; } |
19 | 19 | .controls button:active { transform: translateY(1px); } |
20 | 20 | .controls .hint { color:var(--muted); font-size:12px; margin-left:6px; } |
21 | | - main { display:grid; place-items:center; padding:12px; } |
22 | | - canvas { background:#05070c; border-radius:16px; box-shadow: 0 10px 40px #00000066, inset 0 0 0 1px #1d2433; image-rendering: pixelated; } |
| 21 | + main { display:grid; place-items:center; padding:12px; position:relative; } |
| 22 | + canvas { background:#05070c; border-radius:12px; box-shadow: 0 10px 40px #00000066, inset 0 0 0 1px #1d2433; image-rendering: pixelated; } |
| 23 | + #minimap { position:absolute; top:20px; right:20px; background:#000; border:1px solid #444; border-radius:8px; image-rendering: pixelated; } |
23 | 24 | footer { text-align:center; color:var(--muted); font-size:12px; padding:8px 0 12px; } |
24 | 25 | .kbd { padding:1px 6px; border:1px solid #32415f; border-bottom-width:2px; border-radius:6px; background:#0f1422; color:#c9d2e1; font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; font-size:12px; } |
25 | 26 | </style> |
|
29 | 30 | <h1>Maze Game v2</h1> |
30 | 31 | <div class="controls"> |
31 | 32 | <label>Width (cells) |
32 | | - <input id="w" type="number" min="5" step="2" value="32" /> |
| 33 | + <input id="w" type="number" min="5" step="2" value="41" /> |
33 | 34 | </label> |
34 | 35 | <label>Height (cells) |
35 | | - <input id="h" type="number" min="5" step="2" value="32" /> |
| 36 | + <input id="h" type="number" min="5" step="2" value="41" /> |
36 | 37 | </label> |
37 | 38 | <label>Cell px |
38 | | - <input id="cell" type="number" min="4" max="32" value="20" /> |
| 39 | + <input id="cell" type="number" min="4" max="64" value="16" /> |
39 | 40 | </label> |
40 | 41 | <label>Seed |
41 | 42 | <input id="seed" type="text" placeholder="random" /> |
42 | 43 | </label> |
43 | 44 | <label><input id="showPath" type="checkbox" /> Show solution</label> |
44 | 45 | <button id="regen">Regenerate</button> |
45 | 46 | <button id="reset">Reset Player</button> |
| 47 | + <button id="showSeed">Show Seed</button> |
46 | 48 | <span class="hint">Controls: <span class="kbd">WASD</span>/<span class="kbd">↑←↓→</span>, <span class="kbd">R</span> regen</span> |
47 | 49 | </div> |
48 | 50 | </header> |
49 | 51 | <main> |
50 | 52 | <canvas id="maze"></canvas> |
| 53 | + <canvas id="minimap" width="160" height="160"></canvas> |
51 | 54 | </main> |
| 55 | + <footer> |
| 56 | + Perfect maze — camera locked to player, minimap reveals visited tiles. |
| 57 | + </footer> |
52 | 58 |
|
53 | 59 | <script> |
54 | | - // --- Utilities: PRNG with seed (Mulberry32) --- |
| 60 | + // PRNG (seedable) |
55 | 61 | function xmur3(str){ let h=1779033703^str.length; for(let i=0;i<str.length;i++){h=Math.imul(h^str.charCodeAt(i),3432918353); h=h<<13|h>>>19;} return ()=>{h=Math.imul(h^h>>>16,2246822507); h=Math.imul(h^h>>>13,3266489909); return (h^h>>>16)>>>0;}; } |
56 | 62 | function mulberry32(a){ return function(){ let t=a+=0x6D2B79F5; t=Math.imul(t^t>>>15,t|1); t^=t+Math.imul(t^t>>>7,t|61); return ((t^t>>>14)>>>0)/4294967296; } } |
57 | 63 | function makeRng(seedStr){ if(!seedStr) return Math.random; const seedFn=xmur3(seedStr); return mulberry32(seedFn()); } |
58 | 64 |
|
59 | | - // Grid helpers: We use odd coordinates as "air" cells, even coordinates as walls. |
60 | | - // This produces a classic perfect maze where all air spaces are connected and solvable. |
61 | | - |
62 | 65 | const canvas = document.getElementById('maze'); |
63 | 66 | const ctx = canvas.getContext('2d'); |
| 67 | + const minimap = document.getElementById('minimap'); |
| 68 | + const mctx = minimap.getContext('2d'); |
64 | 69 |
|
65 | | - let grid, W, H, CELL, rng, player, goal; |
| 70 | + let grid, W, H, CELL, rng, player, goal, visited; |
| 71 | + const VIEW = 21; // visible tile window (odd preferred) |
| 72 | + let currentSeed = null; |
66 | 73 |
|
67 | 74 | function initGrid(widthCells, heightCells){ |
68 | | - // Force odd dimensions to maintain the wall/cell pattern. |
69 | 75 | W = widthCells|0; H = heightCells|0; if(W%2===0) W++; if(H%2===0) H++; |
70 | | - grid = Array.from({length:H}, (_,y)=>Array.from({length:W},(_,x)=>1)); // 1=wall, 0=air |
71 | | - // Frame walls remain 1; we'll carve internal passages with randomized DFS. |
| 76 | + grid = Array.from({length:H}, ()=>Array(W).fill(1)); |
| 77 | + visited = Array.from({length:H}, ()=>Array(W).fill(false)); |
72 | 78 | } |
73 | 79 |
|
74 | | - function shuffle(arr){ for(let i=arr.length-1;i>0;i--){ const j=(rng()* (i+1))|0; [arr[i],arr[j]]=[arr[j],arr[i]]; } return arr; } |
| 80 | + function shuffle(arr){ for(let i=arr.length-1;i>0;i--){const j=(rng()*(i+1))|0; [arr[i],arr[j]]=[arr[j],arr[i]];} return arr; } |
75 | 81 |
|
76 | 82 | function carveMaze(){ |
77 | | - // Start at (1,1), carve passages by DFS jumping 2 cells at a time, knocking down walls between. |
78 | | - const stack = [[1,1]]; grid[1][1]=0; |
| 83 | + const stack = [[1,1]]; grid[1][1] = 0; |
79 | 84 | while(stack.length){ |
80 | 85 | const [cx,cy] = stack[stack.length-1]; |
81 | | - // candidates: N S E W two steps away within bounds, still walls (unvisited cells) |
82 | 86 | const dirs = shuffle([[0,-2],[0,2],[2,0],[-2,0]]); |
83 | 87 | let carved = false; |
84 | 88 | for(const [dx,dy] of dirs){ |
85 | | - const nx=cx+dx, ny=cy+dy; |
| 89 | + const nx = cx+dx, ny = cy+dy; |
86 | 90 | if(ny>0 && ny<H-1 && nx>0 && nx<W-1 && grid[ny][nx]===1){ |
87 | | - // Knock down the wall between (cx,cy) and (nx,ny) |
88 | | - grid[cy+dy/2][cx+dx/2]=0; // middle wall |
89 | | - grid[ny][nx]=0; // new cell |
90 | | - stack.push([nx,ny]); |
91 | | - carved = true; |
92 | | - break; |
| 91 | + grid[cy+dy/2][cx+dx/2] = 0; grid[ny][nx] = 0; |
| 92 | + stack.push([nx,ny]); carved = true; break; |
93 | 93 | } |
94 | 94 | } |
95 | 95 | if(!carved) stack.pop(); |
96 | 96 | } |
97 | | - // Select start/goal on opposite edges of the carved region for nice paths |
98 | | - player = {x:1, y:1}; |
| 97 | + player = {x:1,y:1}; |
99 | 98 | goal = farthestFrom(player); |
100 | | - // Optionally, place player at farthest from goal, to maximize path length |
101 | 99 | player = farthestFrom(goal); |
102 | 100 | } |
103 | 101 |
|
104 | | - function farthestFrom(start){ |
105 | | - const dist = bfsDistances(start.x, start.y); |
106 | | - let max= -1, pos=start; |
107 | | - for(let y=1;y<H;y+=2){ |
108 | | - for(let x=1;x<W;x+=2){ |
109 | | - if(dist[y][x]!==Infinity && dist[y][x]>max){ max=dist[y][x]; pos={x,y}; } |
110 | | - } |
111 | | - } |
112 | | - return pos; |
113 | | - } |
114 | | - |
115 | 102 | function bfsDistances(sx,sy){ |
116 | | - const dist = Array.from({length:H},()=>Array(W).fill(Infinity)); |
117 | | - const q=[[sx,sy]]; dist[sy][sx]=0; |
118 | | - const moves=[[1,0],[-1,0],[0,1],[0,-1]]; |
| 103 | + const dist = Array.from({length:H}, ()=>Array(W).fill(Infinity)); |
| 104 | + const q = [[sx,sy]]; dist[sy][sx]=0; |
| 105 | + const moves = [[1,0],[-1,0],[0,1],[0,-1]]; |
119 | 106 | while(q.length){ |
120 | | - const [x,y]=q.shift(); |
| 107 | + const [x,y] = q.shift(); |
121 | 108 | for(const [dx,dy] of moves){ |
122 | | - const nx=x+dx, ny=y+dy; |
123 | | - if(nx>=0&&nx<W&&ny>=0&&ny<H && grid[ny][nx]===0 && dist[ny][nx]===Infinity){ |
124 | | - dist[ny][nx]=dist[y][x]+1; q.push([nx,ny]); |
| 109 | + const nx = x+dx, ny = y+dy; |
| 110 | + if(nx>=0 && ny>=0 && nx<W && ny<H && grid[ny][nx]===0 && dist[ny][nx]===Infinity){ |
| 111 | + dist[ny][nx] = dist[y][x] + 1; q.push([nx,ny]); |
125 | 112 | } |
126 | 113 | } |
127 | 114 | } |
128 | 115 | return dist; |
129 | 116 | } |
130 | 117 |
|
| 118 | + function farthestFrom(start){ |
| 119 | + const dist = bfsDistances(start.x, start.y); |
| 120 | + let max = -1, pos = {x:start.x,y:start.y}; |
| 121 | + for(let y=1;y<H;y+=2){ for(let x=1;x<W;x+=2){ if(dist[y][x]!==Infinity && dist[y][x] > max){ max = dist[y][x]; pos = {x,y}; } } } |
| 122 | + return pos; |
| 123 | + } |
| 124 | + |
131 | 125 | function shortestPath(from, to){ |
132 | | - // Reconstruct one shortest path via BFS parents |
133 | | - const dist=bfsDistances(from.x, from.y); |
| 126 | + const dist = bfsDistances(from.x, from.y); |
134 | 127 | if(dist[to.y][to.x]===Infinity) return []; |
135 | | - const path=[[to.x,to.y]]; |
136 | | - const moves=[[1,0],[-1,0],[0,1],[0,-1]]; |
137 | | - let [x,y]=[to.x,to.y]; |
| 128 | + const path = [[to.x,to.y]]; |
| 129 | + const moves = [[1,0],[-1,0],[0,1],[0,-1]]; |
| 130 | + let [x,y] = [to.x,to.y]; |
138 | 131 | while(x!==from.x || y!==from.y){ |
139 | | - let best=null, bestd=Infinity; |
| 132 | + let best = null, bestd = Infinity; |
140 | 133 | for(const [dx,dy] of moves){ |
141 | | - const nx=x+dx, ny=y+dy; |
142 | | - if(nx>=0&&nx<W&&ny>=0&&ny<H && dist[ny][nx] < bestd){ |
143 | | - bestd=dist[ny][nx]; best=[nx,ny]; |
144 | | - } |
| 134 | + const nx = x+dx, ny = y+dy; |
| 135 | + if(nx>=0 && ny>=0 && nx<W && ny<H && dist[ny][nx] < bestd){ bestd = dist[ny][nx]; best = [nx,ny]; } |
145 | 136 | } |
146 | | - if(!best) break; // should not happen in perfect maze |
147 | | - [x,y]=best; path.push([x,y]); |
| 137 | + if(!best) break; |
| 138 | + [x,y] = best; path.push([x,y]); |
148 | 139 | } |
149 | 140 | return path.reverse(); |
150 | 141 | } |
151 | 142 |
|
152 | 143 | function draw(){ |
153 | | - const pad=8; canvas.width = W*CELL + pad*2; canvas.height = H*CELL + pad*2; |
154 | | - ctx.fillStyle = '#03060b'; ctx.fillRect(0,0,canvas.width, canvas.height); |
155 | | - |
156 | | - // Draw maze |
157 | | - for(let y=0;y<H;y++){ |
158 | | - for(let x=0;x<W;x++){ |
159 | | - const px = pad + x*CELL, py = pad + y*CELL; |
160 | | - if(grid[y][x]===1){ |
161 | | - // walls next to air by construction; render them slightly glossy |
162 | | - ctx.fillStyle = '#101826'; |
163 | | - ctx.fillRect(px,py,CELL,CELL); |
164 | | - ctx.fillStyle = 'rgba(255,255,255,0.04)'; |
165 | | - ctx.fillRect(px,py, CELL, Math.max(1, CELL*0.15)); |
166 | | - } else { |
167 | | - ctx.fillStyle = '#0c1220'; |
168 | | - ctx.fillRect(px,py,CELL,CELL); |
169 | | - } |
| 144 | + canvas.width = VIEW * CELL; |
| 145 | + canvas.height = VIEW * CELL; |
| 146 | + ctx.fillStyle = '#03060b'; ctx.fillRect(0,0,canvas.width,canvas.height); |
| 147 | + const half = VIEW >> 1; |
| 148 | + for(let dy=-half; dy<=half; dy++){ |
| 149 | + for(let dx=-half; dx<=half; dx++){ |
| 150 | + const worldX = player.x + dx; |
| 151 | + const worldY = player.y + dy; |
| 152 | + const sx = (dx + half) * CELL; |
| 153 | + const sy = (dy + half) * CELL; |
| 154 | + if(worldX >= 0 && worldY >= 0 && worldX < W && worldY < H){ |
| 155 | + if(grid[worldY][worldX] === 1){ ctx.fillStyle = '#101826'; ctx.fillRect(sx, sy, CELL, CELL); ctx.fillStyle='rgba(255,255,255,0.04)'; ctx.fillRect(sx, sy, CELL, Math.max(1, CELL*0.12)); } |
| 156 | + else { ctx.fillStyle = '#0c1220'; ctx.fillRect(sx, sy, CELL, CELL); } |
| 157 | + } else { ctx.fillStyle = '#0b0f16'; ctx.fillRect(sx, sy, CELL, CELL); } |
170 | 158 | } |
171 | 159 | } |
172 | | - |
173 | | - // Draw solution path if toggled |
174 | 160 | if(document.getElementById('showPath').checked){ |
175 | 161 | const path = shortestPath(player, goal); |
176 | | - ctx.globalAlpha = 0.9; |
177 | | - for(const [x,y] of path){ |
178 | | - const px = pad + x*CELL, py = pad + y*CELL; |
179 | | - ctx.fillStyle = '#6ee7ff'; |
180 | | - ctx.fillRect(px+CELL*0.25, py+CELL*0.25, CELL*0.5, CELL*0.5); |
| 162 | + ctx.globalAlpha = 0.95; |
| 163 | + for(const [px,py] of path){ |
| 164 | + const dx = px - player.x; const dy = py - player.y; |
| 165 | + if(Math.abs(dx) <= half && Math.abs(dy) <= half){ |
| 166 | + const sx = (dx + half) * CELL + CELL*0.25; |
| 167 | + const sy = (dy + half) * CELL + CELL*0.25; |
| 168 | + ctx.fillStyle = '#6ee7ff'; ctx.fillRect(sx, sy, CELL*0.5, CELL*0.5); |
| 169 | + } |
181 | 170 | } |
182 | 171 | ctx.globalAlpha = 1; |
183 | 172 | } |
184 | | - |
185 | | - // Draw goal |
186 | | - ;{ |
187 | | - const gx = pad + goal.x*CELL, gy = pad + goal.y*CELL; |
188 | | - ctx.fillStyle = '#a7f3d0'; |
189 | | - ctx.beginPath(); |
190 | | - ctx.roundRect(gx+CELL*0.15, gy+CELL*0.15, CELL*0.7, CELL*0.7, 4); |
191 | | - ctx.fill(); |
| 173 | + const gdx = goal.x - player.x, gdy = goal.y - player.y; |
| 174 | + if(Math.abs(gdx) <= half && Math.abs(gdy) <= half){ |
| 175 | + const gsx = (gdx + half) * CELL + CELL*0.15; |
| 176 | + const gsy = (gdy + half) * CELL + CELL*0.15; |
| 177 | + ctx.fillStyle = '#a7f3d0'; ctx.fillRect(gsx, gsy, CELL*0.7, CELL*0.7); |
192 | 178 | } |
| 179 | + const center = half * CELL; |
| 180 | + ctx.fillStyle = '#e5e7eb'; ctx.fillRect(center + CELL*0.2, center + CELL*0.2, CELL*0.6, CELL*0.6); |
| 181 | + visited[player.y][player.x] = true; |
| 182 | + drawMinimap(); |
| 183 | + } |
193 | 184 |
|
194 | | - // Draw player |
195 | | - const px = pad + player.x*CELL, py = pad + player.y*CELL; |
196 | | - ctx.fillStyle = '#e5e7eb'; |
197 | | - ctx.beginPath(); |
198 | | - ctx.roundRect(px+CELL*0.2, py+CELL*0.2, CELL*0.6, CELL*0.6, 4); |
199 | | - ctx.fill(); |
| 185 | + function drawMinimap(){ |
| 186 | + const mw = minimap.width, mh = minimap.height; |
| 187 | + const scaleX = mw / W, scaleY = mh / H; |
| 188 | + mctx.fillStyle = '#000'; mctx.fillRect(0,0,mw,mh); |
| 189 | + for(let y=0;y<H;y++){ |
| 190 | + for(let x=0;x<W;x++){ |
| 191 | + if(!visited[y][x]) continue; |
| 192 | + mctx.fillStyle = grid[y][x]===0 ? '#0c1220' : '#101826'; |
| 193 | + mctx.fillRect(x*scaleX, y*scaleY, scaleX, scaleY); |
| 194 | + } |
| 195 | + } |
| 196 | + mctx.fillStyle = '#e5e7eb'; mctx.fillRect(player.x*scaleX, player.y*scaleY, scaleX, scaleY); |
| 197 | + mctx.fillStyle = '#a7f3d0'; mctx.fillRect(goal.x*scaleX, goal.y*scaleY, scaleX, scaleY); |
200 | 198 | } |
201 | 199 |
|
202 | 200 | function regenerate(){ |
203 | | - const w = Math.max(5, parseInt(document.getElementById('w').value,10)||31); |
204 | | - const h = Math.max(5, parseInt(document.getElementById('h').value,10)||31); |
205 | | - CELL = Math.max(4, Math.min(32, parseInt(document.getElementById('cell').value,10)||16)); |
| 201 | + const w = Math.max(5, parseInt(document.getElementById('w').value,10) || 31); |
| 202 | + const h = Math.max(5, parseInt(document.getElementById('h').value,10) || 31); |
| 203 | + CELL = Math.max(4, Math.min(64, parseInt(document.getElementById('cell').value,10) || 16)); |
206 | 204 | const seedStr = document.getElementById('seed').value.trim(); |
207 | | - rng = makeRng(seedStr || null); |
208 | | - initGrid(w, h); |
| 205 | + currentSeed = seedStr || (Math.random() + '').slice(2); |
| 206 | + rng = makeRng(seedStr || currentSeed); |
| 207 | + |
| 208 | + initGrid(w,h); |
209 | 209 | carveMaze(); |
| 210 | + |
| 211 | + visited = Array.from({length:H}, ()=>Array(W).fill(false)); |
| 212 | + visited[player.y][player.x] = true; |
| 213 | + |
| 214 | + canvas.width = VIEW * CELL; canvas.height = VIEW * CELL; |
| 215 | + |
210 | 216 | draw(); |
211 | 217 | } |
212 | 218 |
|
213 | 219 | function tryMove(dx,dy){ |
214 | | - const nx = player.x + dx; const ny = player.y + dy; |
215 | | - if(nx<0||ny<0||nx>=W||ny>=H) return; // out of bounds |
216 | | - if(grid[ny][nx]===0){ player.x=nx; player.y=ny; draw(); checkWin(); } |
| 220 | + const nx = player.x + dx, ny = player.y + dy; |
| 221 | + if(nx<0||ny<0||nx>=W||ny>=H) return; |
| 222 | + if(grid[ny][nx]===0){ player.x = nx; player.y = ny; draw(); checkWin(); } |
217 | 223 | } |
218 | 224 |
|
219 | | - function checkWin(){ |
220 | | - if(player.x===goal.x && player.y===goal.y){ |
221 | | - flashWin(); |
222 | | - } |
223 | | - } |
| 225 | + function checkWin(){ if(player.x===goal.x && player.y===goal.y) flashWin(); } |
224 | 226 |
|
225 | 227 | function flashWin(){ |
226 | | - // Simple celebratory pulse |
227 | | - let t=0, id=null; |
| 228 | + let t=0; |
228 | 229 | function step(){ |
229 | | - t+=0.05; draw(); |
230 | | - const pad=8; const x = 8 + player.x*CELL + CELL/2; const y=8 + player.y*CELL + CELL/2; |
231 | | - ctx.save(); ctx.translate(x,y); ctx.globalAlpha = Math.max(0, 1.2 - t); |
232 | | - ctx.beginPath(); ctx.arc(0,0, Math.max(0,CELL*1.2*t), 0, Math.PI*2); |
233 | | - ctx.strokeStyle = '#6ee7ff'; ctx.lineWidth = 3; ctx.stroke(); ctx.restore(); |
234 | | - if(t<1.2) id=requestAnimationFrame(step); |
| 230 | + draw(); |
| 231 | + const half = VIEW>>1; |
| 232 | + const cx = half*CELL + CELL*0.5, cy = cx; |
| 233 | + ctx.save(); |
| 234 | + ctx.globalAlpha = Math.max(0,1.2 - t); |
| 235 | + ctx.strokeStyle = '#6ee7ff'; |
| 236 | + ctx.lineWidth = 3; |
| 237 | + ctx.beginPath(); |
| 238 | + ctx.arc(cx, cy, CELL*1.2*t, 0, Math.PI*2); |
| 239 | + ctx.stroke(); |
| 240 | + ctx.restore(); |
| 241 | + t+=0.06; |
| 242 | + if(t<1.2) requestAnimationFrame(step); |
| 243 | + else { |
| 244 | + document.getElementById('seed').value = ''; |
| 245 | + currentSeed = (Math.random() + '').slice(2); |
| 246 | + rng = makeRng(currentSeed); |
| 247 | + regenerate(); |
| 248 | + } |
235 | 249 | } |
236 | 250 | step(); |
237 | 251 | } |
238 | 252 |
|
239 | | - // Input |
| 253 | + // movement |
240 | 254 | window.addEventListener('keydown', (e)=>{ |
241 | | - const k=e.key.toLowerCase(); |
| 255 | + const k = e.key.toLowerCase(); |
242 | 256 | if(k==='arrowup' || k==='w') tryMove(0,-1); |
243 | 257 | else if(k==='arrowdown' || k==='s') tryMove(0,1); |
244 | 258 | else if(k==='arrowleft' || k==='a') tryMove(-1,0); |
245 | 259 | else if(k==='arrowright' || k==='d') tryMove(1,0); |
246 | | - else if(k==='r'){ regenerate(); } |
| 260 | + else if(k==='r') regenerate(); |
247 | 261 | }); |
248 | 262 |
|
249 | 263 | document.getElementById('regen').addEventListener('click', regenerate); |
250 | | - document.getElementById('reset').addEventListener('click', ()=>{ player=farthestFrom(goal); draw(); }); |
| 264 | + document.getElementById('reset').addEventListener('click', ()=>{ player = {x:1,y:1}; visited = Array.from({length:H}, ()=>Array(W).fill(false)); visited[player.y][player.x]=true; draw();}); |
251 | 265 | document.getElementById('showPath').addEventListener('change', draw); |
| 266 | + document.getElementById('showSeed').addEventListener('click', () => { |
| 267 | + document.getElementById('seed').value = currentSeed; |
| 268 | + }); |
252 | 269 |
|
253 | | - // Kick off |
254 | 270 | (function start(){ |
255 | | - document.getElementById('w').value = 31; |
256 | | - document.getElementById('h').value = 31; |
| 271 | + document.getElementById('w').value = 41; |
| 272 | + document.getElementById('h').value = 41; |
257 | 273 | document.getElementById('cell').value = 16; |
258 | | - regenerate(); |
| 274 | + currentSeed = (Math.random() + '').slice(2); |
| 275 | + rng = makeRng(currentSeed); |
| 276 | + initGrid(41,41); |
| 277 | + carveMaze(); |
| 278 | + CELL = parseInt(document.getElementById('cell').value,10) || 16; |
| 279 | + canvas.width = VIEW * CELL; canvas.height = VIEW * CELL; |
| 280 | + visited[player.y][player.x] = true; |
| 281 | + draw(); |
259 | 282 | })(); |
260 | 283 | </script> |
261 | 284 | </body> |
|
0 commit comments