Last active
March 23, 2023 15:17
-
-
Save pcornier/81e9556b2a2170212893 to your computer and use it in GitHub Desktop.
Godot GDScript - An implementation of A* path finding algorithm for tilemap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends TileMap | |
const WALKABLE = 2 | |
var cells = Vector2Array() | |
func _ready(): | |
cells = get_used_cells() | |
pass | |
func find_path(map_from, map_to): | |
var list = [] | |
list.append({'g': 0, 'f': 0, 'pt': map_from, 'parent': -1}) | |
while (list.size()): | |
var idx = _smallest_f(list) | |
var c = list[idx] | |
list.remove(idx) | |
if (c.pt == map_to): | |
var path = [] | |
while c.parent != -1: | |
c = c.parent | |
path.append(map_to_world(c.pt)) | |
return path | |
for y in [-1, 0, 1]: | |
for x in [-1, 0, 1]: | |
if x == 0 && y == 0: | |
continue | |
var pos = c.pt + Vector2(x, y) | |
var h = abs(pos.x - map_to.x) + abs(pos.y - map_to.y) | |
var nb = {'g': c.g + 1, 'f': h + c.g + 1, 'pt': pos, 'parent': c} | |
var idx = _search_in_list(pos, list) | |
if idx && list[idx].g > nb.g: | |
list[idx] = nb | |
if WALKABLE == _search_in_cells(pos): | |
list.append(nb) | |
return [] | |
func _search_in_list(pt, list): | |
for i in range(list.size()): | |
if list[i].pt == pt: | |
return i | |
return false | |
func _search_in_cells(p): | |
for i in cells: | |
if i == p: | |
return get_cell(p.x, p.y) | |
func _smallest_f(list): | |
var idx = 0 | |
for i in range(list.size()): | |
if list[i].f < list[idx].f: | |
idx = i | |
return idx | |
func is_walkable(world_pos): | |
var map_pos = world_to_map(world_pos) | |
return get_cell(map_pos.x, map_pos.y) == WALKABLE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment