Find a path from startPos to endPos in world space. Returns an array * of world-space Vector2 points; empty array if no path exists. * * Start and end are snapped to the nearest walkable tile via * getNearestClearNode. Intermediate points are tile centers unless the * st
(startPos, endPos)
| 741 | * @returns {Vector2[]} |
| 742 | * @memberof PathFinding */ |
| 743 | findPath(startPos, endPos) |
| 744 | { |
| 745 | ASSERT(isVector2(startPos) && isVector2(endPos), 'findPath needs Vector2 endpoints'); |
| 746 | |
| 747 | this.buildNodeData(); |
| 748 | |
| 749 | // rebuild=false because we just built — avoid redundant work per snap. |
| 750 | const startNode = this.getNearestClearNode(startPos, 10, false); |
| 751 | const endNode = this.getNearestClearNode(endPos, 10, false); |
| 752 | if (!startNode || !endNode) return []; |
| 753 | |
| 754 | // Trivial case: start and end snapped to the same tile. |
| 755 | if (startNode === endNode) return [startNode.posWorld.copy()]; |
| 756 | |
| 757 | if (!this.aStarSearch(startNode, endNode)) return []; |
| 758 | |
| 759 | // Walk back from endNode via parent pointers, then reverse — cheaper |
| 760 | // than unshifting on every step. |
| 761 | const nodePath = []; |
| 762 | for (let n = endNode; n; n = n.parent) |
| 763 | nodePath.push(n); |
| 764 | nodePath.reverse(); |
| 765 | |
| 766 | if (this.smoothPath) |
| 767 | { |
| 768 | this.smoothPathCorners(nodePath); |
| 769 | this.smoothPathStringPull(nodePath); |
| 770 | this.dropCollinearNodes(nodePath); |
| 771 | } |
| 772 | |
| 773 | // Convert to world-space Vector2 path. Return copies, not live node |
| 774 | // references — callers shouldn't be able to mutate the grid. |
| 775 | const result = nodePath.map(n => n.posWorld.copy()); |
| 776 | |
| 777 | if (this.debug && this.debugTime > 0 && result.length > 0) |
| 778 | { |
| 779 | for (let i = 1; i < result.length; ++i) |
| 780 | debugLine(result[i - 1], result[i], RED, 0.1, this.debugTime); |
| 781 | for (const p of result) |
| 782 | debugCircle(p, 0.5, rgb(1, 0, 0, 0.3), this.debugTime); |
| 783 | debugCircle(result[0], 0.5, rgb(0, 1, 0, 0.5), this.debugTime); |
| 784 | debugCircle(result[result.length - 1], 0.5, rgb(0, 1, 0, 0.5), this.debugTime); |
| 785 | } |
| 786 | |
| 787 | return result; |
| 788 | } |
| 789 | } |
no test coverage detected