js实现随机圆形迷宫生成器代码

代码语言:html

所属分类:其他

代码描述:js实现随机圆形迷宫生成器代码

代码标签: 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