js实现随机圆形迷宫生成器代码
代码语言:html
所属分类:其他
代码描述:js实现随机圆形迷宫生成器代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { margin: 0; overflow: hidden; } p { font-family: sans-serif; position: absolute; bottom: 0; width: 100%; text-align: center; } svg { width: 100vw; height: 100vh; } line, circle { fill: none; stroke: #000; stroke-width: 4; stroke-linecap: square; } path { fill: none; stroke: #080; stroke-width: 4; stroke-linejoin: round; stroke-linecap: round; display: none; pointer-events: none; } #center { pointer-events: all; cursor: pointer; } #center:hover ~ path { display: inline; } </style> </head> <body> <svg></svg> <p>Touch/hover the center to see how to reach it. <a href="javascript:init()">Reload</a> to get a new maze.</p> <script> // rings at which to half the width of a // field, counting outwards. // ring 1 is the first pathway outside the center // and allways has 8 fields const keys = [1,2,4,8]; // counting the innermost wall as 2, // radius of the outermost wall const maxC = 15; const root = document.querySelector('svg'); const size = maxC * 20 + 50; root.setAttribute('viewBox', [-size, -size, 2*size, 2*size].join(' ')); const round = [...Array(maxC)].map((_,i) => 2 ** (keys.findLastIndex(j => j < i+1)) * 8); const maxP = round.slice(-1)[0]; const chooseFrom = a => a[Math.random() * a.length | 0]; const polarToCartesian = (r, f) => [ r * 20 * Math.cos(f * 2 * Math.PI), r * 20 * Math.sin(f * 2 * Math.PI) ]; const sectorsToDashes = sectors => { let offset = 0, array = [], last = false; sectors.forEach((s, i) => { if (s === last) { if (array.length) { array[array.length - 1]++; } else { offset++; } } else { array.push(1); } last = s; }); if (array.length) { array[array.length - 1] += offset; } else { array.push(offset); } return [array.join(' '), -offset]; } class Cell { #doubles = keys.slice(1); #halfes = this.#doubles.map(j => j - 1); constructor (c, p) { this.c = c; this.p = p; this.maze = false; } get polarCoordinates () { return { r: this.c + 1.5, f: (this.p * 2 + 1) / round[this.c] / 2 } } get outsideMore () { return this.#halfes.includes(this.c); } get insideLess () { return this.#doubles.includes(this.c); } get neighbours () { const list = []; const r = round[this.c]; list.push([this.c, (this.p - 1 + r) % r]); list.push([this.c, (this.p + 1) % r]); if (this.insideLess) { list.push([this.c - 1, this.p >> 1]); } else if (this.c > 1) { list.push([this.c - 1, this.p]); } if (this.outsideMore) { list.push([this.c + 1, this.p * 2]); list.push([this.c + 1, this.p * 2 + 1]); } else if (this.c < maxC - 2) { list.push([this.c + 1, this.p]); } return list; } after (cell) { return (this.p || round[this.c]) - cell?.p == 1; } getWall (cell) { if (cell.c < this.c) { return ['c', this.c + 1, this.p]; } else if (cell.c > this.c) { return ['c', cell.c + 1, cell.p]; } else { const higher = this.after(cell) ? this : cell; const ray = higher.p * maxP / round[higher.c]; return ['p', ray, this.c]; } } } class CircularWall { constructor (radius) { this.r = radius; const sectors = round[radius - 1]; this.sectors = Array(sectors).fill(true); this.circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); if (radius == 2) this.circle.setAttribute('id', 'center'); this.circle.setAttribute('r', radius * 20); this.circle.setAttribute('pathLength', sectors); root..........完整代码请登录后点击上方下载按钮下载查看
网友评论0