From 89b2660d6941a72ed36fef9ac7ec7d7c78d35953 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Mon, 30 Jun 2025 16:09:02 +0000 Subject: [PATCH] Migrate Navigation AStar demo to TileMapLayer and perform various cleanups (#1208) * navigation_astar: replace deprecated TileMap with TileMapLayer * navigation_astar: use get_used_cells() instead of iterating over region This also removes the confusing use of Tile.OBSTACLE. The tile enum is mostly used for atlas coordinates but in this case it is compared with the source id which only happens to be zero as well. * navigation_astar: use constants for atlas coordinates This makes it more obvious how to set cells in larger tilesets where the second position is not zero. It also removes the constant OBSTACLE which is unused since the last commit. * navigation_astar: mention get_used_rect() Using it in this example is more complex (as the border has no cells) but it's good to know. --- 2d/navigation_astar/character.gd | 2 +- 2d/navigation_astar/game.tscn | 7 +++--- 2d/navigation_astar/pathfind_astar.gd | 35 +++++++++++++++------------ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/2d/navigation_astar/character.gd b/2d/navigation_astar/character.gd index 799ec2df..5ea353ff 100644 --- a/2d/navigation_astar/character.gd +++ b/2d/navigation_astar/character.gd @@ -19,7 +19,7 @@ var _click_position := Vector2() var _path := PackedVector2Array() var _next_point := Vector2() -@onready var _tile_map: PathFindAStar = $"../TileMap" +@onready var _tile_map: PathFindAStar = $"../TileMapLayer" func _ready() -> void: _change_state(State.IDLE) diff --git a/2d/navigation_astar/game.tscn b/2d/navigation_astar/game.tscn index d6ce243f..1e26ae8f 100644 --- a/2d/navigation_astar/game.tscn +++ b/2d/navigation_astar/game.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=3 uid="uid://0g57p64tiyqn"] +[gd_scene load_steps=10 format=4 uid="uid://0g57p64tiyqn"] [ext_resource type="Texture2D" uid="uid://baj4xukvf568b" path="res://sprites/space.png" id="1_2jdkd"] [ext_resource type="TileSet" uid="uid://f3wmg8detyai" path="res://tileset/tileset.tres" id="2_aylbj"] @@ -28,10 +28,9 @@ colors = PackedColorArray(1, 0.893555, 0, 1, 0.265625, 1, 0.490903, 1, 0.0154343 texture = ExtResource("1_2jdkd") offset = Vector2(576, 324) -[node name="TileMap" type="TileMap" parent="."] +[node name="TileMapLayer" type="TileMapLayer" parent="."] +tile_map_data = PackedByteArray("AAABAAEAAAAAAAAAAAAFAAEAAAAAAAAAAAAJAAEAAAAAAAAAAAAOAAEAAAAAAAAAAAAJAAMAAAAAAAAAAAAKAAMAAAAAAAAAAAALAAMAAAAAAAAAAAAIAAMAAAAAAAAAAAAHAAMAAAAAAAAAAAAGAAMAAAAAAAAAAAADAAQAAAAAAAAAAAACAAQAAAAAAAAAAAABAAQAAAAAAAAAAAADAAUAAAAAAAAAAAADAAYAAAAAAAAAAAAEAAYAAAAAAAAAAAAFAAYAAAAAAAAAAAAGAAYAAAAAAAAAAAABAAgAAAAAAAAAAAACAAgAAAAAAAAAAAADAAgAAAAAAAAAAAAEAAgAAAAAAAAAAAAFAAgAAAAAAAAAAAAGAAgAAAAAAAAAAAAHAAgAAAAAAAAAAAAIAAgAAAAAAAAAAAAJAAgAAAAAAAAAAAAJAAcAAAAAAAAAAAAKAAYAAAAAAAAAAAALAAYAAAAAAAAAAAAMAAYAAAAAAAAAAAAPAAcAAAAAAAAAAAAPAAYAAAAAAAAAAAAPAAUAAAAAAAAAAAAPAAQAAAAAAAAAAAAQAAMAAAAAAAAAAAANAAQAAAAAAAAAAAA=") tile_set = ExtResource("2_aylbj") -format = 2 -layer_0/tile_data = PackedInt32Array(65537, 0, 0, 65541, 0, 0, 65545, 0, 0, 65550, 0, 0, 196617, 0, 0, 196618, 0, 0, 196619, 0, 0, 196616, 0, 0, 196615, 0, 0, 196614, 0, 0, 262147, 0, 0, 262146, 0, 0, 262145, 0, 0, 327683, 0, 0, 393219, 0, 0, 393220, 0, 0, 393221, 0, 0, 393222, 0, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 458761, 0, 0, 393226, 0, 0, 393227, 0, 0, 393228, 0, 0, 458767, 0, 0, 393231, 0, 0, 327695, 0, 0, 262159, 0, 0, 196624, 0, 0, 262157, 0, 0) script = ExtResource("3_taaih") [node name="Character" type="Marker2D" parent="."] diff --git a/2d/navigation_astar/pathfind_astar.gd b/2d/navigation_astar/pathfind_astar.gd index 9233c871..bfa5f8bd 100644 --- a/2d/navigation_astar/pathfind_astar.gd +++ b/2d/navigation_astar/pathfind_astar.gd @@ -1,10 +1,8 @@ -extends TileMap +extends TileMapLayer -enum Tile { - OBSTACLE, - START_POINT, - END_POINT, -} +# Atlas coordinates in tile set for start/end tiles. +const TILE_START_POINT = Vector2i(1, 0) +const TILE_END_POINT = Vector2i(2, 0) const CELL_SIZE = Vector2i(64, 64) const BASE_LINE_WIDTH: float = 3.0 @@ -20,6 +18,7 @@ var _path := PackedVector2Array() func _ready() -> void: # Region should match the size of the playable area plus one (in tiles). # In this demo, the playable area is 17×9 tiles, so the rect size is 18×10. + # Depending on the setup TileMapLayer's get_used_rect() can also be used. _astar.region = Rect2i(0, 0, 18, 10) _astar.cell_size = CELL_SIZE _astar.offset = CELL_SIZE * 0.5 @@ -28,11 +27,17 @@ func _ready() -> void: _astar.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER _astar.update() - for i in range(_astar.region.position.x, _astar.region.end.x): - for j in range(_astar.region.position.y, _astar.region.end.y): - var pos := Vector2i(i, j) - if get_cell_source_id(0, pos) == Tile.OBSTACLE: - _astar.set_point_solid(pos) + # Iterate over all cells on the tile map layer and mark them as + # non-passable. + for pos in get_used_cells(): + _astar.set_point_solid(pos) + # To skip cells with certain atlas coordinates you can use: + # if get_cell_atlas_coords(pos) == Vector2i(42, 23): + # ... + # You can also add a "Custom Data Layer" to the tile set to group + # tiles and check it here; in the following example using a string: + # if get_cell_tile_data(pos).get_custom_data("type") == "obstacle": + # ... func _draw() -> void: @@ -61,8 +66,8 @@ func is_point_walkable(local_position: Vector2) -> bool: func clear_path() -> void: if not _path.is_empty(): _path.clear() - erase_cell(0, _start_point) - erase_cell(0, _end_point) + erase_cell(_start_point) + erase_cell(_end_point) # Queue redraw to clear the lines and circles. queue_redraw() @@ -75,8 +80,8 @@ func find_path(local_start_point: Vector2i, local_end_point: Vector2i) -> Packed _path = _astar.get_point_path(_start_point, _end_point) if not _path.is_empty(): - set_cell(0, _start_point, 0, Vector2i(Tile.START_POINT, 0)) - set_cell(0, _end_point, 0, Vector2i(Tile.END_POINT, 0)) + set_cell(_start_point, 0, TILE_START_POINT) + set_cell(_end_point, 0, TILE_END_POINT) # Redraw the lines and circles from the start to the end point. queue_redraw()