disable collision to fix pathfinding phasing through walls

This commit is contained in:
2024-12-25 03:55:32 +09:00
parent 3bb34ed012
commit f48a6bf9aa
4 changed files with 71 additions and 28 deletions
+27 -18
View File
@@ -3,28 +3,33 @@ import PriorityQueue from "./priority-queue.js"
import SATX from "./satx.js"
export default class Pathfind {
static keyFor(pos) {
return `${pos.x},${pos.y}`
}
static shortestPath(graph, start, goal) {
const key = (pos) => `${pos.x},${pos.y}`
const queue = new PriorityQueue((a, b) => a[1] < b[1])
const visited = new Map()
queue.push([[start], 0])
queue.push([[[start, null]], 0])
while (!queue.isEmpty()) {
const [path, cost] = queue.pop()
const waypoint = path.at(-1)
const waypoint = path.at(-1).at(0)
if (waypoint.equals(goal)) {
path.shift()
return path
}
if (!visited.has(key(waypoint)) || visited.get(key(waypoint)) > cost) {
visited.set(key(waypoint), cost)
const key = this.keyFor(waypoint)
if (!visited.has(key) || visited.get(key) > cost) {
visited.set(key, cost)
for (const { to, distance } of graph.filter(e => e.from.equals(waypoint))) {
if (!visited.has(key(to)) || visited.get(key(to)) > cost + distance) {
queue.push([[...path, to], cost + distance])
for (const { to, direction, distance } of graph.filter(e => e.from.equals(waypoint))) {
const keyTo = this.keyFor(to)
if (!visited.has(keyTo) || visited.get(keyTo) > cost + distance) {
queue.push([[...path, [to, direction]], cost + distance])
}
}
}
@@ -33,24 +38,28 @@ export default class Pathfind {
return []
}
static buildGraph(waypoints = [], colliders = [], radius = 0) {
static buildGraph(toWaypoints, colliders, fromWaypoints = null) {
const graph = []
const calculated = new Set()
for (const from of waypoints) {
for (const to of waypoints) {
for (const [from, reverseDirection] of (fromWaypoints ?? toWaypoints)) {
for (const [to, direction] of toWaypoints) {
if (from.equals(to)) {
continue
}
const tunnel = SATX.entityTunnel(from, to, radius)
const collider = Entity.collider(from.x, from.y, radius)
const key = `${from.x},${from.y};${to.x},${to.y}`
if (!calculated.has(key)) {
calculated.add(key)
calculated.add(`${to.x},${to.y};${from.x},${from.y}`)
const tunnelClear = !SATX.collideObjects(tunnel, colliders)
const waypointAvailable = !SATX.collideObjects(collider, colliders)
const lineOfSight = !SATX.collideObjects(SATX.line(from, to), colliders)
if (waypointAvailable && tunnelClear) {
const distance = from.distanceTo(to)
graph.push({ from, to, distance })
if (lineOfSight) {
const distance = from.distanceTo(to)
graph.push({ from, to, distance, direction })
graph.push({ to: from, from: to, distance, direction: reverseDirection })
}
}
}
}