UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

114 lines (112 loc) 3.12 kB
import { Vector2 } from "three/src/Three"; import { PathNode } from "./PathNode"; export class Pathfinder { ol; nl; ll; Cr; constructor(t, e = .5, i = .5, o = 1e3) { this.Cr = t?.slice() ?? []; this.ol = e; this.nl = i; this.ll = o; } addCollideMap(t) { this.Cr.push(t); } removeCollideMap(t) { const e = this.Cr.indexOf(t); if (e >= 0) { this.Cr.splice(e, 1); } } removeAllCollideMaps() { this.Cr.length = 0; } findPath(t, e) { const i = new PathNode(t.x, t.y); const o = new PathNode(e.x, e.y); if (this.Sh(i.x, i.y)) return null; if (this.Sh(o.x, o.y)) return null; const r = []; const n = []; i.gCost = 0; i.hCost = this.al(i, o); i.calculateFCost(); r.push(i); let s = 0; while (r.length > 0 && s < this.ll) { s += 1; const t = this.cl(r); if (t.equals(o)) { return this.ul(t); } r.splice(r.indexOf(t), 1); n.push(t); const e = this.dl(t); for (let i = 0; i < e.length; ++i) { const s = e[i]; if (n.find((t => t.equals(s))) !== undefined) continue; else { s.gCost = Number.MAX_VALUE; s.calculateFCost(); s.previousNode = null; } if (this.Sh(s.x, s.y)) { n.push(s); continue; } const h = t.gCost + this.al(t, s); if (h < s.gCost) { s.previousNode = t; s.gCost = h; s.hCost = this.al(s, o); s.calculateFCost(); if (r.find((t => t.equals(s))) === undefined) { r.push(s); } } } } return null; } dl(t) { const e = []; e.push(new PathNode(t.x, t.y - 1)); e.push(new PathNode(t.x + 1, t.y)); e.push(new PathNode(t.x, t.y + 1)); e.push(new PathNode(t.x - 1, t.y)); return e; } ul(t) { const e = []; let i = t; while (i.previousNode) { e.push(new Vector2(i.x, i.y)); i = i.previousNode; } e.push(new Vector2(i.x, i.y)); return e.reverse(); } al(t, e) { return Math.abs(t.x - e.x) + Math.abs(t.y - e.y); } cl(t) { let e = t[0]; for (let i = 1; i < t.length; ++i) { if (t[i].fCost < e.fCost) { e = t[i]; } } return e; } Sh(t, e) { const i = this.Cr; for (let o = 0; o < i.length; ++o) { const r = i[o]; if (r.checkCollision(t * r.gridCellWidth + r.gridCenterX, e * r.gridCellHeight + r.gridCenterY, this.ol, this.nl)) { return true; } } return false; } }