用户:
145a查看:7 回复:6 评论:7 创建时间:2024-02-03T11:13:51
/*145a的第一个寻路代码*/
"use strict";
class PathNode {
constructor(position, father, g, h) {
this.position = position;
this.father = father;
this.g = g;
this.h = h;
}
get f() {
return this.g + this.h;
}
copy(node) {
this.position = node.position;
this.father = node.father;
this.g = node.g;
this.h = node.h;
}
clone() {
return new PathNode(this.position, this.father, this.g, this.h);
}
}
async function aStar(startPos, endPos, bounds = new GameBounds3(new GameVector3(0, 0, 0), new GameVector3(256, 喵, 256))) {
startPos.x = Math.round(startPos.x);
startPos.y = Math.round(startPos.y);
startPos.z = Math.round(startPos.z);
//console.log("开始寻路", startPos, endPos);
const open = [new PathNode(startPos, null, 0, 0)];
const path = [];
const close = [];
while (true) {
if (close.length >= 10 ** 4) return null;
if (open.length === 0 || open[0].position.distance(endPos) < 1) {
//console.log("退出寻路循环", close.length);
break;
}
//if (close.length % 10000 === 0) console.log("寻路中,剩余",open.length);
//voxels.setVoxel(open[0].position.x, open[0].position.y, open[0].position.z, "yellow_light");
//console.log(open[0].position, "g", open[0].g, "h", open[0].h, "f", open[0].f)
//world.say(open.length)
if (close.length % 100 === 0) await sleep(1);
//voxels.setVoxel(open[0].position.x, open[0].position.y, open[0].position.z, "glass");
close.push(open[0].position);
let nextList = [
new GameVector3(1, 0, 0),
new GameVector3(-1, 0, 0),
new GameVector3(0, 1, 0),
new GameVector3(0, -1, 0),
new GameVector3(0, 0, 1),
new GameVector3(0, 0, -1)
].map(v =>
open[0].position.add(v)
).filter(next =>
voxels.getVoxel(next.x, next.y, next.z) === 0
&& !close.some(v => next.exactEquals(v))
).map(v =>
new PathNode(v, open[0], open[0].g + 1, v.distance(endPos))
);
for (const node of nextList) {
const samePosNode = open.find((n) => n.position.exactEquals(node.position));
if (samePosNode) {
if (samePosNode.f > nextList.f || (samePosNode.f === nextList.f && samePosNode.h > nextList.h)) {
console.log(copy)
samePosNode.copy(node);
}
} else {
open.push(node);
}
}
open.shift();
open.sort((a, b) => a.f===b.f?a.f - b.f:a.h - b.h);
}
if (!open[0]) {
//console.log("没有可用道路");
return null;
} else {
let currentNode = open[0];
while (!currentNode.position.equals(startPos)) {
currentNode = currentNode.father;
path.unshift(currentNode.position);
}
}
//path.forEach(v => {voxels.setVoxel(v.x, v.y, v.z, "green")})
//console.log("寻路完成", path.length);
return path;
}
voxels.findPath = aStar;
/*
void async function () {
let nodes = await aStar(new GameVector3(90,30,59), new GameVector3(133,3,239))
nodes.forEach(v => { voxels.setVoxel(v.x, v.y, v.z, "green_light") })
}()
*/
//请勿删除最后一行