Pārlūkot izejas kodu

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.
Simon Ruderich 2 mēneši atpakaļ
vecāks
revīzija
89b2660d69

+ 1 - 1
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)

+ 3 - 4
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="."]

+ 20 - 15
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()