daedalus/MazeMesh.js
2023-06-06 17:10:19 +02:00

68 lines
2.1 KiB
JavaScript

import * as THREE from 'three';
const mazeGeometry = new THREE.BoxGeometry( 1, 1, 1 );
export default class MazeMesh extends THREE.InstancedMesh {
constructor( width, length, material ) {
super( mazeGeometry, material, width*length - 2 );
this.length = length
this.width = width
this.map = new Array(length).fill().map(() => new Array(width).fill(1))
this.start = new THREE.Vector3(width/2, .1, length/2)
this.exit = new THREE.Vector3(Math.floor(width/2), 0, 1)
this.count = length * width - 2
this.dig(this.exit)
this.dig(new THREE.Vector3(Math.floor(width/2), 0, 0))
this.build ( this.exit )
let matrix = new THREE.Matrix4()
let i=0
this.map.forEach((row, z) => {
row.forEach((isWall, x) => {
if (isWall) {
matrix.setPosition( x + .5 - width/2, 0.5, z + .5 - length/2)
this.setMatrixAt( i, matrix );
i++
}
})
})
}
dig(position) {
this.map[position.z][position.x] = 0
}
static DIRECTIONS = [
new THREE.Vector3( 0, 0, -1),
new THREE.Vector3( 0, 0, 1),
new THREE.Vector3(-1, 0, 0),
new THREE.Vector3( 1, 0, 0),
]
build(position) {
for (var direction of Array.from(this.constructor.DIRECTIONS).sort(x => .5 - Math.random())) {
var step1 = position.clone().add(direction)
var step2 = step1.clone().add(direction)
if (this.isWall(step2) == 1) {
this.dig(step1)
this.dig(step2)
this.count -= 2
this.build(step2)
}
}
}
isWall(position) {
if (0 <= position.x && position.x < this.width &&
0 <= position.z && position.z < this.length) {
return this.map[Math.floor(position.z)][Math.floor(position.x)]
} else {
return -1
}
}
toString() {
return this.map.map(row =>
row.map(isWall => isWall? "██":"░░").join("")
).join("\n")
}
}