49 lines
1.8 KiB
GDScript
49 lines
1.8 KiB
GDScript
## PathfindingHandler.gd
|
|||
|
|
# Handles A* pathfinding for the map using Godot's AStar2D.
|
||
|
|
# Builds a navigation graph from walkable tiles and provides path queries.
|
||
|
|
class_name PathfindingHandler
|
||
|
|
extends RefCounted
|
||
|
|
|
||
|
|
# All 8 possible neighbor offsets (cardinal and diagonal directions).
|
||
|
|
const NEIGHBORS: Array[Vector2i] = [
|
||
|
|
Vector2i.RIGHT, Vector2i.LEFT, Vector2i.DOWN, Vector2i.UP,
|
||
|
|
Vector2i(1, 1), Vector2i(1, -1), Vector2i(-1, 1), Vector2i(-1, -1),
|
||
|
|
]
|
||
|
|
|
||
|
|
# The underlying AStar2D instance for pathfinding.
|
||
|
|
var _astar: AStar2D = AStar2D.new()
|
||
|
|
# Maps grid coordinates (Vector2i) to AStar2D point IDs.
|
||
|
|
var _coord_to_id: Dictionary = {}
|
||
|
|
|
||
|
|
# Builds the AStar2D graph from all walkable tiles in MapData.
|
||
|
|
# Safe to call again for a new level — clears all previous state first.
|
||
|
|
func build(data: MapData) -> void:
|
||
|
|
_astar.clear()
|
||
|
|
_coord_to_id.clear()
|
||
|
|
|
||
|
|
# Register a point for every walkable tile (FLOOR).
|
||
|
|
for coords: Vector2i in data.grid.keys():
|
||
|
|
if data.grid[coords] == MapData.TileType.FLOOR:
|
||
|
|
var id: int = _astar.get_available_point_id()
|
||
|
|
_astar.add_point(id, Vector2(coords.x, coords.y))
|
||
|
|
_coord_to_id[coords] = id
|
||
|
|
|
||
|
|
# Connect each point to its walkable neighbors (cardinal and diagonal).
|
||
|
|
for coords: Vector2i in _coord_to_id.keys():
|
||
|
|
for offset: Vector2i in NEIGHBORS:
|
||
|
|
var neighbor: Vector2i = coords + offset
|
||
|
|
if _coord_to_id.has(neighbor):
|
||
|
|
_astar.connect_points(_coord_to_id[coords], _coord_to_id[neighbor], false)
|
||
|
|
|
||
|
|
# Returns the path as grid coordinates, or an empty array if no path exists.
|
||
|
|
# Used by LevelManager and Player for navigation.
|
||
|
|
func find_path(from: Vector2i, to: Vector2i) -> Array[Vector2i]:
|
||
|
|
if not _coord_to_id.has(from) or not _coord_to_id.has(to):
|
||
|
|
return []
|
||
|
|
|
||
|
|
var raw: PackedVector2Array = _astar.get_point_path(_coord_to_id[from], _coord_to_id[to])
|
||
|
|
var result: Array[Vector2i] = []
|
||
|
|
for point in raw:
|
||
|
|
result.append(Vector2i(point))
|
||
|
|
return result
|