Files
shadow-pixel-run/map/pathfinding_handler.gd
T

49 lines
1.8 KiB
GDScript
Raw Normal View History

## 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