I have a grid layout with AStar2D, to which I added the visuals to show the path it will take. It uses sprites from a png tileset of 4x4. Both $GridTerrain and $GridArrow are tilemaps.
The good news is it works flawless. However, as the code clearly shows, I gave up on a clever way to solve this, and simply brute forced everything in there.
How would you handle this? Is this code to slow to run every frame? Know of any tutorial or example code that will go in depth to grid based pathing?
extends Node2D var cellSize = Vector2(64, 64) var path: PoolVector2Array #these directly relate to the spritesheet (4x4), with all arrow pathing possibilities enum {PATH_CROSS, PATH_CENTER, PATH_WEST_EAST, PATH_SOUTH_NORTH, PATH_START_NORTH, PATH_START_EAST, PATH_START_SOUTH, PATH_START_WEST, PATH_NORTH_EAST, PATH_EAST_SOUTH, PATH_SOUTH_WEST, PATH_WEST_NORTH, PATH_END_NORTH, PATH_END_EAST, PATH_END_SOUTH, PATH_END_WEST} enum{NORTH, EAST, SOUTH, WEST} func _process(delta): var from = Vector2(7, 7) #just a random point to test the code var to = worldToGrid(get_viewport().get_mouse_position()) path = $GridTerrain.getPath(from, to) #this gets a PoolVector2Array filled by AStar2D drawPath() func drawPath(): $GridArrow.clear() if path.size() > 1: # is the path at least 2 segments long? var count = 0 var lastCardinal = NORTH for point in path: if count == 0: #start of path match cardinalNextCell(point, path[count + 1]): NORTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_START_NORTH)) lastCardinal = SOUTH EAST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_START_EAST)) lastCardinal = WEST SOUTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_START_SOUTH)) lastCardinal = NORTH WEST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_START_WEST)) lastCardinal = EAST elif count < path.size() - 1: #before the end point? var nextCardinal = cardinalNextCell(point, path[count + 1]) match lastCardinal: NORTH: if nextCardinal == SOUTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_SOUTH_NORTH)) elif nextCardinal == WEST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_WEST_NORTH)) lastCardinal = EAST else: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_NORTH_EAST)) lastCardinal = WEST EAST: if nextCardinal == WEST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_WEST_EAST)) elif nextCardinal == SOUTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_EAST_SOUTH)) lastCardinal = NORTH else: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_NORTH_EAST)) lastCardinal = SOUTH SOUTH: if nextCardinal == NORTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_SOUTH_NORTH)) elif nextCardinal == EAST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_EAST_SOUTH)) lastCardinal = WEST else: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_SOUTH_WEST)) lastCardinal = EAST WEST: if nextCardinal == EAST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_WEST_EAST)) elif nextCardinal == SOUTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_SOUTH_WEST)) lastCardinal = NORTH else: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_WEST_NORTH)) lastCardinal = SOUTH else: #the end point match lastCardinal: NORTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_END_SOUTH)) EAST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_END_WEST)) SOUTH: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_END_NORTH)) WEST: $GridArrow.set_cell(point.x, point.y, 0, false, false, false, getPathTile(PATH_END_EAST)) count += 1 func worldToGrid(target: Vector2) -> Vector2: var newCoord = Vector2.ZERO newCoord.x = floor(target.x / cellSize.x) newCoord.y = floor(target.y / cellSize.y) return newCoord func gridToWorld(target: Vector2) -> Vector2: var newCoord = Vector2.ZERO newCoord.x *= cellSize.x newCoord.y *= cellSize.y return newCoord func getPathTile(target: int) -> Vector2: #subtile from pathing tileset return Vector2((target % 4), floor(target / 4)) func cardinalNextCell(current: Vector2, next: Vector2) -> int: if current.x > next.x: return WEST elif current.x < next.x: return EAST elif current.y > next.y: return NORTH else: return SOUTH