Created
September 9, 2020 15:51
-
-
Save ryanmunger/90ef9877d803075abf114080053481bd to your computer and use it in GitHub Desktop.
astar walkable tiles issue
This file contains 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 | |
# You can only create an AStar node from code, not from the Scene tab | |
onready var astar_node = AStar2D.new() | |
# The Tilemap node doesn't have clear bounds so we're defining the map's limits here | |
export(Vector2) var map_size = Vector2(16, 16) | |
# The path start and end variables use setter methods | |
# You can find them at the bottom of the script | |
var path_start_position = Vector2() setget _set_path_start_position | |
var path_end_position = Vector2() setget _set_path_end_position | |
var _point_path = [] | |
var _current_steps = [] | |
const BASE_LINE_WIDTH = 3.0 | |
const DRAW_COLOR = Color('#fff') | |
# get_used_cells_by_id is a method from the TileMap node | |
# here the id 0 corresponds to the grey tile, the obstacles | |
onready var tiles = get_used_cells() | |
onready var obstacles = get_used_cells_by_id(0) | |
onready var _half_cell_size = cell_size / 2 | |
func _ready(): | |
var walkable_cells_list = show_walkable_cells(obstacles) | |
astar_connect_walkable_cells_diagonal(walkable_cells_list) | |
func show_walkable_cells(obstacles = []): | |
var points_array = [] | |
var player_position = world_to_map(get_parent().get_node("Character").position) | |
for x in range(5): | |
for y in range(5): | |
var walkable_tile = player_position + Vector2(x - 2, y - 2) | |
if walkable_tile in obstacles: | |
continue | |
if is_outside_map_bounds(walkable_tile): | |
continue | |
points_array.append(walkable_tile) | |
# The AStar class references points with indices | |
# Using a function to calculate the index from a point's coordinates | |
# ensures we always get the same index with the same input point | |
var point_index = calculate_point_index(walkable_tile) | |
# AStar works for both 2d and 3d, so we have to convert the point | |
# coordinates from and to Vector3s | |
astar_node.add_point(point_index, Vector2(walkable_tile.x, walkable_tile.y)) | |
return points_array | |
# This is a variation of the method above | |
# It connects cells horizontally, vertically AND diagonally | |
func astar_connect_walkable_cells_diagonal(points_array): | |
var point_paths = [] | |
var player_index = calculate_point_index(world_to_map(get_parent().get_node("Character").position)) | |
for point in points_array: | |
var point_index = calculate_point_index(point) | |
for local_y in range(3): | |
for local_x in range(3): | |
var point_relative = Vector2(point.x + local_x - 1, point.y + local_y - 1) | |
var point_relative_index = calculate_point_index(point_relative) | |
point_paths.append(astar_node.get_point_path(player_index, point_relative_index)) | |
# print("player_index: " + str(player_index) + " " + "point_relative: " + str(point_relative) + " " + "point_relative_index: " + str(point_relative_index) + " " + "astar_paths: " + str(astar_node.get_point_path(player_index, point_relative_index))) | |
if point_relative == point or is_outside_map_bounds(point_relative): | |
continue | |
if not astar_node.has_point(point_relative_index): | |
continue | |
astar_node.connect_points(point_index, point_relative_index, true) | |
# print("point_paths: " + str(astar_node.get_point_path(player_index, point_relative_index))) | |
# print("point_relative: " + str(point_relative)) | |
# print("point: " + str(point)) | |
# print("player index: " + str(player_index)) | |
if point_relative in astar_node.get_point_path(player_index, point_relative_index): | |
set_cell(point_relative.x, point_relative.y, 3) | |
print(point_paths) | |
func is_outside_map_bounds(point): | |
return point.x < 0 or point.y < 0 or point.x >= map_size.x or point.y >= map_size.y | |
func calculate_point_index(point): | |
return point.x + map_size.x * point.y | |
func find_path(world_start, world_end): | |
self.path_start_position = world_to_map(world_start) | |
self.path_end_position = world_to_map(world_end) | |
_recalculate_path() | |
var path_world = [] | |
for point in _point_path: | |
var point_world = map_to_world(Vector2(point.x, point.y)) + _half_cell_size | |
path_world.append(point_world) | |
return path_world | |
func _recalculate_path(): | |
var start_point_index = calculate_point_index(path_start_position) | |
var end_point_index = calculate_point_index(path_end_position) | |
# This method gives us an array of points. Note you need the start and end | |
# points' indices as input | |
_point_path = astar_node.get_point_path(start_point_index, end_point_index) | |
# Redraw the lines and circles from the start to the end point | |
update() | |
# Setters for the start and end path values. | |
func _set_path_start_position(value): | |
if value in obstacles: | |
return | |
if is_outside_map_bounds(value): | |
return | |
path_start_position = value | |
if path_end_position and path_end_position != path_start_position: | |
_recalculate_path() | |
func _set_path_end_position(value): | |
if value in obstacles: | |
return | |
if is_outside_map_bounds(value): | |
return | |
# set_cell(path_start_position.x, path_start_position.y, -1) | |
# set_cell(value.x, value.y, 2) | |
path_end_position = value | |
if path_start_position != value: | |
_recalculate_path() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The place where I am setting the "visiliby walkable tiles" is line 73.