From 2a22d3865c7a36e0064f90da831ede531c5eb919 Mon Sep 17 00:00:00 2001 From: Yan Wittmann Date: Tue, 19 Nov 2024 13:52:51 +0100 Subject: [PATCH] Mario Party --- .../scenes/mario-party/MPNavigationGraph.gd | 92 ++++++----- .../scenes/mario-party/MPNavigationNode.gd | 2 + .../scenes/mario-party/MPPathfindingResult.gd | 21 +++ .../scenes/mario-party/Mar849B.tmp | 54 +++++++ .../scenes/mario-party/MarioParty.tscn | 36 ++++- .../mario-party/MarioPartyManagement.gd | 150 +++++++++++++++--- .../scenes/mario-party/PlayerController.gd | 59 +++++++ .../scenes/mario-party/TileIndicator.tscn | 19 +++ .../scenes/mario-party/img/tile_highlight.png | Bin 0 -> 642 bytes .../mario-party/img/tile_highlight.png.import | 34 ++++ .../scenes/mario-party/img/tile_node.png | Bin 0 -> 551 bytes .../mario-party/img/tile_node.png.import | 34 ++++ .../scenes/mario-party/tile_indicator.gd | 26 +++ 13 files changed, 461 insertions(+), 66 deletions(-) create mode 100644 pathfinding-algorithms/scenes/mario-party/MPPathfindingResult.gd create mode 100644 pathfinding-algorithms/scenes/mario-party/Mar849B.tmp create mode 100644 pathfinding-algorithms/scenes/mario-party/PlayerController.gd create mode 100644 pathfinding-algorithms/scenes/mario-party/TileIndicator.tscn create mode 100644 pathfinding-algorithms/scenes/mario-party/img/tile_highlight.png create mode 100644 pathfinding-algorithms/scenes/mario-party/img/tile_highlight.png.import create mode 100644 pathfinding-algorithms/scenes/mario-party/img/tile_node.png create mode 100644 pathfinding-algorithms/scenes/mario-party/img/tile_node.png.import create mode 100644 pathfinding-algorithms/scenes/mario-party/tile_indicator.gd diff --git a/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd b/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd index 8b79907..b6cd3bb 100644 --- a/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd +++ b/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd @@ -1,61 +1,61 @@ class_name MPNavigationGraph extends Node2D -# godot does not support types on dictionaries, actual type is Dictionary[NavigationNode, Array[NavigationNode]] -var navigation_nodes: Dictionary = {} -var latest_navigation_result: PathfindingResult = null -var draw_nodes: bool = true -var draw_edges: bool = true +# godot does not support types on dictionaries, actual type is Dictionary[MPNavigationNode, Array[MPNavigationNode]] +var navigation_nodes: Dictionary = {} +var latest_navigation_result: MPPathfindingResult = null +var draw_nodes: bool = false +var draw_edges: bool = false -func all_nodes() -> Array[NavigationNode]: +func all_nodes() -> Array[MPNavigationNode]: # i've had a problem where godot would not allow me to directly return navigation_nodes.keys() - # because it wasn't able to cast the keys to Array[NavigationNode] directly because the type is not explicit + # because it wasn't able to cast the keys to Array[MPNavigationNode] directly because the type is not explicit # on the dictionary, so i had to do this workaround. - var keys: Array = navigation_nodes.keys() - var nodes: Array[NavigationNode] = [] + var keys: Array = navigation_nodes.keys() + var nodes: Array[MPNavigationNode] = [] for key in keys: - if key is NavigationNode: + if key is MPNavigationNode: nodes.append(key) else: - push_error("Key is not a NavigationNode: %s" % key) + push_error("Key is not a MPNavigationNode: %s" % key) return nodes -func get_connections(from: NavigationNode) -> Array[NavigationNode]: +func get_connections(from: MPNavigationNode) -> Array[MPNavigationNode]: # the same problem as the all_nodes() function - var connections: Array = navigation_nodes[from] - var nodes: Array[NavigationNode] = [] + var connections: Array = navigation_nodes[from] + var nodes: Array[MPNavigationNode] = [] for connection in connections: - if connection is NavigationNode: + if connection is MPNavigationNode: nodes.append(connection) else: - push_error("Connection is not a NavigationNode: %s" % connection) + push_error("Connection is not a MPNavigationNode: %s" % connection) return nodes -func add_connection(from: NavigationNode, to: NavigationNode) -> void: +func add_connection(from: MPNavigationNode, to: MPNavigationNode) -> void: if all_nodes().has(from): navigation_nodes[from].append(to) else: navigation_nodes[from] = [to] -func add_node(x: float, y: float, merge_threshold: float = -1.0) -> NavigationNode: +func add_node(x: float, y: float, merge_threshold: float = -1.0) -> MPNavigationNode: if merge_threshold > 0: - var closest_node: NavigationNode = find_closest_node_with_threshold(Vector2(x, y), merge_threshold) + var closest_node: MPNavigationNode = find_closest_node_with_threshold(Vector2(x, y), merge_threshold) if closest_node: closest_node.was_merged = true return closest_node - var node: NavigationNode = NavigationNode.new() + var node: MPNavigationNode = MPNavigationNode.new() node.set_position(Vector2(x, y)) navigation_nodes[node] = [] return node -func find_closest_node_with_threshold(position: Vector2, threshold: float) -> NavigationNode: - var closest_node: NavigationNode = null - var closest_distance: float = threshold +func find_closest_node_with_threshold(position: Vector2, threshold: float) -> MPNavigationNode: + var closest_node: MPNavigationNode = null + var closest_distance: float = threshold for node in all_nodes(): var distance: float = position.distance_to(node.position) if distance < closest_distance: @@ -64,12 +64,12 @@ func find_closest_node_with_threshold(position: Vector2, threshold: float) -> Na return closest_node -func remove_connection(from: NavigationNode, to: NavigationNode) -> void: +func remove_connection(from: MPNavigationNode, to: MPNavigationNode) -> void: if all_nodes().has(from): navigation_nodes[from].erase(to) -func remove_node(node: NavigationNode) -> void: +func remove_node(node: MPNavigationNode) -> void: navigation_nodes.erase(node) for other_node in all_nodes(): if other_node != node: @@ -77,7 +77,6 @@ func remove_node(node: NavigationNode) -> void: func _draw() -> void: - print("Drawing navigation graph") if draw_nodes or draw_edges: for from in all_nodes(): if draw_edges: @@ -90,24 +89,31 @@ func _draw() -> void: if latest_navigation_result.path.size() > 1: for i in range(latest_navigation_result.path.size() - 1): draw_line(local_to_world(latest_navigation_result.path[i].position), local_to_world(latest_navigation_result.path[i + 1].position), Color.GREEN, 1, false) - draw_circle(local_to_world(latest_navigation_result.next_position), 5, Color.GREEN) + for node in latest_navigation_result.path: + draw_circle(local_to_world(node.position), 5, Color.GREEN) func local_to_world(location: Vector2) -> Vector2: return location * 32 + Vector2(16, 16) -func draw_pathfinding_result(result: PathfindingResult) -> void: + +func draw_pathfinding_result(result: MPPathfindingResult) -> void: if latest_navigation_result and latest_navigation_result.is_identical_to(result): return latest_navigation_result = result queue_redraw() -func determine_next_position(current_position: Vector2, target_position: Vector2) -> PathfindingResult: - var result: PathfindingResult = PathfindingResult.new() +func clear_pathfinding_result() -> void: + latest_navigation_result = null + queue_redraw() + + +func determine_next_position(current_position: Vector2, target_position: Vector2) -> MPPathfindingResult: + var result: MPPathfindingResult = MPPathfindingResult.new() # Find the closest node to the current position - var start_node: NavigationNode = find_closest_node_with_threshold(current_position, INF) + var start_node: MPNavigationNode = find_closest_node_with_threshold(current_position, INF) if start_node == null: # No nodes exist; cannot navigate result.is_next_target = true @@ -115,7 +121,7 @@ func determine_next_position(current_position: Vector2, target_position: Vector2 return result # Find the closest node to the target position - var end_node: NavigationNode = find_closest_node_with_threshold(target_position, INF) + var end_node: MPNavigationNode = find_closest_node_with_threshold(target_position, INF) if end_node == null: # No nodes exist; cannot navigate result.is_next_target = true @@ -129,7 +135,7 @@ func determine_next_position(current_position: Vector2, target_position: Vector2 return result # Run Dijkstra's algorithm to find the path - var path: Array[NavigationNode] = dijkstra(start_node, end_node) + var path: Array[MPNavigationNode] = dijkstra(start_node, end_node) result.path = path # If a path is found, return the position of the next node in the path @@ -149,26 +155,26 @@ func determine_next_position(current_position: Vector2, target_position: Vector2 return result -func array_contains_node(arr: Array, node: NavigationNode) -> bool: +func array_contains_node(arr: Array, node: MPNavigationNode) -> bool: for item in arr: if item == node: return true return false -func dijkstra(start_node: NavigationNode, end_node: NavigationNode) -> Array[NavigationNode]: - var open_set: Array[NavigationNode] = [] - var closed_set: Array[NavigationNode] = [] - var distances: Dictionary = {} - var previous_nodes: Dictionary = {} +func dijkstra(start_node: MPNavigationNode, end_node: MPNavigationNode) -> Array[MPNavigationNode]: + var open_set: Array[MPNavigationNode] = [] + var closed_set: Array[MPNavigationNode] = [] + var distances: Dictionary = {} + var previous_nodes: Dictionary = {} distances[start_node] = 0 open_set.append(start_node) while open_set.size() > 0: # Find the node with the smallest tentative distance - var current_node: NavigationNode = open_set[0] - var current_distance: float = distances[current_node] + var current_node: MPNavigationNode = open_set[0] + var current_distance: float = distances[current_node] for node in open_set: if distances[node] < current_distance: current_node = node @@ -176,8 +182,8 @@ func dijkstra(start_node: NavigationNode, end_node: NavigationNode) -> Array[Nav # If the end node is reached, reconstruct the path if current_node == end_node: - var path: Array[NavigationNode] = [] - var node: NavigationNode = end_node + var path: Array[MPNavigationNode] = [] + var node: MPNavigationNode = end_node while node != null: path.insert(0, node) node = previous_nodes.get(node, null) diff --git a/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd b/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd index 2a2d7cb..c869672 100644 --- a/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd +++ b/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd @@ -1,2 +1,4 @@ class_name MPNavigationNode extends Node2D + +var was_merged: bool = false diff --git a/pathfinding-algorithms/scenes/mario-party/MPPathfindingResult.gd b/pathfinding-algorithms/scenes/mario-party/MPPathfindingResult.gd new file mode 100644 index 0000000..e9ba7c5 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/MPPathfindingResult.gd @@ -0,0 +1,21 @@ +class_name MPPathfindingResult +extends Node + +var path: Array[MPNavigationNode] = [] +var next_position: Vector2 = Vector2.ZERO +var is_next_target: bool = false + +func _init() -> void: + path = [] + next_position = Vector2.ZERO + is_next_target = false + +func is_identical_to(other: MPPathfindingResult) -> bool: + if path.size() != other.path.size(): + return false + for i in range(path.size()): + if path[i] != other.path[i]: + return false + if next_position != other.next_position: + return false + return true diff --git a/pathfinding-algorithms/scenes/mario-party/Mar849B.tmp b/pathfinding-algorithms/scenes/mario-party/Mar849B.tmp new file mode 100644 index 0000000..da6d208 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/Mar849B.tmp @@ -0,0 +1,54 @@ +[gd_scene load_steps=7 format=4 uid="uid://ddlksorhs8rls"] + +[ext_resource type="TileSet" uid="uid://cm6wi7fjgfk56" path="res://scenes/mario-party/MarioPartyTiles.tres" id="1_3jghe"] +[ext_resource type="Script" path="res://scenes/mario-party/MarioPartyManagement.gd" id="1_r0jft"] +[ext_resource type="Script" path="res://scenes/mario-party/MPNavigationGraph.gd" id="3_ww84c"] +[ext_resource type="Script" path="res://scenes/mario-party/PlayerController.gd" id="4_djnau"] +[ext_resource type="Texture2D" uid="uid://c53ftc05so8rx" path="res://icon.svg" id="5_3opuj"] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_cgpao"] +radius = 24.9999 +height = 49.9999 + +[node name="MarioParty" type="Node2D"] +script = ExtResource("1_r0jft") + +[node name="GroundLayer" type="TileMapLayer" parent="."] +scale = Vector2(2, 2) +tile_map_data = PackedByteArray("AAAAAAAAAgAFAAEAAAABAAAAAgAEAAAAAAACAAAAAgADAAAAAAADAAAAAgABAAEAAAAEAAAAAgAAAAEAAAAEAAEAAgAAAAAAAAAAAAEAAgACAAAAAAAAAAIAAgACAAEAAAAAAAMAAgAFAAAAAAAAAAQAAgADAAAAAAAAAAUAAgAAAAAAAAAAAAYAAgABAAAAAAAAAAcAAgABAAAAAAAAAAgAAgAFAAAAAAAAAAkAAgAAAAAAAAAAAAoAAgACAAAAAAAAAAsAAgADAAAAAAAAAAwAAgAEAAEAAAAAAA0AAgAEAAEAAAAAAA4AAgABAAAAAAAAAA8AAgAAAAAAAAAAABAAAgABAAEAAAAAABEAAgADAAEAAAAAABIAAgAFAAAAAAAAABMAAgACAAAAAAABAAEAAgAFAAEAAAABAAIAAgADAAAAAAABAAMAAgADAAAAAAABAAQAAgAFAAEAAAABAAUAAgADAAEAAAABAAYAAgACAAAAAAABAAcAAgAAAAEAAAABAAgAAgADAAAAAAABAAkAAgADAAAAAAABAAoAAgAEAAEAAAABAAsAAgACAAEAAAABAAwAAgACAAAAAAABAA0AAgAAAAAAAAABAA4AAgAFAAAAAAABAA8AAgAEAAAAAAABABAAAgAEAAAAAAABABEAAgABAAEAAAABABIAAgAEAAEAAAABABMAAgABAAAAAAACAAEAAgAEAAAAAAACAAIAAgABAAAAAAACAAMAAgAEAAEAAAACAAQAAgAAAAAAAAACAAUAAgAFAAAAAAACAAYAAgABAAAAAAACAAcAAgAFAAAAAAACAAgAAgAEAAEAAAACAAkAAgAFAAAAAAACAAoAAgADAAEAAAACAAsAAgAEAAEAAAACAAwAAgADAAAAAAACAA0AAgABAAEAAAACAA4AAgAFAAAAAAACAA8AAgACAAAAAAACABAAAgACAAAAAAACABEAAgAEAAAAAAACABIAAgABAAEAAAACABMAAgADAAEAAAADAAEAAgABAAAAAAADAAIAAgAAAAEAAAADAAMAAgADAAEAAAADAAQAAgABAAAAAAADAAUAAgACAAAAAAADAAYAAgACAAAAAAADAAcAAgADAAAAAAADAAgAAgABAAAAAAADAAkAAgAAAAEAAAADAAoAAgADAAEAAAADAAsAAgAAAAEAAAADAAwAAgAEAAAAAAADAA0AAgAFAAEAAAADAA4AAgAAAAEAAAADAA8AAgADAAEAAAADABAAAgACAAEAAAADABEAAgAAAAEAAAADABIAAgABAAAAAAADABMAAgADAAEAAAAEAAIAAgABAAAAAAAEAAMAAgAAAAAAAAAEAAQAAgAFAAAAAAAEAAUAAgAEAAAAAAAEAAYAAgABAAEAAAAEAAcAAgABAAEAAAAEAAgAAgABAAEAAAAEAAkAAgADAAEAAAAEAAoAAgAEAAAAAAAEAAsAAgAAAAAAAAAEAAwAAgAFAAAAAAAEAA0AAgAFAAAAAAAEAA4AAgAAAAAAAAAEAA8AAgAEAAAAAAAEABAAAgACAAEAAAAEABEAAgADAAEAAAAEABIAAgAAAAAAAAAEABMAAgACAAAAAAAFAAAAAgABAAEAAAAFAAEAAgAEAAEAAAAFAAIAAgABAAEAAAAFAAMAAgAFAAEAAAAFAAQAAgAAAAEAAAAFAAUAAgACAAEAAAAFAAYAAgACAAEAAAAFAAcAAgAAAAEAAAAFAAgAAgAFAAEAAAAFAAkAAgAAAAEAAAAFAAoAAgAEAAEAAAAFAAsAAgAAAAEAAAAFAAwAAgAAAAAAAAAFAA0AAgADAAEAAAAFAA4AAgADAAAAAAAFAA8AAgADAAEAAAAFABAAAgAFAAEAAAAFABEAAgAEAAAAAAAFABIAAgADAAAAAAAFABMAAgAAAAEAAAAGAAAAAgAAAAEAAAAGAAEAAgAFAAEAAAAGAAIAAgAEAAEAAAAGAAMAAgAFAAEAAAAGAAQAAgAAAAAAAAAGAAUAAgADAAAAAAAGAAYAAgADAAAAAAAGAAcAAgAEAAEAAAAGAAgAAgACAAEAAAAGAAkAAgACAAAAAAAGAAoAAgAAAAAAAAAGAAsAAgADAAAAAAAGAAwAAgAAAAEAAAAGAA0AAgABAAEAAAAGAA4AAgADAAEAAAAGAA8AAgAEAAEAAAAGABAAAgABAAEAAAAGABEAAgAAAAAAAAAGABIAAgAAAAEAAAAGABMAAgABAAAAAAAHAAAAAgADAAEAAAAHAAEAAgABAAEAAAAHAAIAAgAFAAEAAAAHAAMAAgAEAAAAAAAHAAQAAgAEAAEAAAAHAAUAAgACAAAAAAAHAAYAAgAFAAAAAAAHAAcAAgACAAAAAAAHAAgAAgAAAAAAAAAHAAkAAgACAAAAAAAHAAoAAgAFAAEAAAAHAAsAAgABAAEAAAAHAAwAAgAEAAEAAAAHAA0AAgABAAAAAAAHAA4AAgAFAAAAAAAHAA8AAgAAAAEAAAAHABAAAgAFAAEAAAAHABEAAgABAAAAAAAHABIAAgAFAAAAAAAHABMAAgADAAAAAAAIAAAAAgAFAAAAAAAIAAEAAgAAAAEAAAAIAAIAAgAAAAAAAAAIAAMAAgACAAAAAAAIAAQAAgAAAAAAAAAIAAUAAgACAAAAAAAIAAYAAgADAAEAAAAIAAcAAgAEAAEAAAAIAAgAAgABAAEAAAAIAAkAAgAFAAEAAAAIAAoAAgADAAEAAAAIAAsAAgAFAAEAAAAIAAwAAgACAAAAAAAIAA0AAgACAAAAAAAIAA4AAgACAAEAAAAIAA8AAgAEAAAAAAAIABAAAgAAAAEAAAAIABEAAgAFAAAAAAAIABIAAgADAAAAAAAIABMAAgAFAAEAAAAJAAAAAgABAAAAAAAJAAEAAgADAAEAAAAJAAIAAgAAAAEAAAAJAAMAAgADAAAAAAAJAAQAAgADAAAAAAAJAAUAAgAAAAEAAAAJAAYAAgAFAAEAAAAJAAcAAgACAAAAAAAJAAgAAgABAAAAAAAJAAkAAgAFAAAAAAAJAAoAAgAAAAEAAAAJAAsAAgADAAAAAAAJAAwAAgAFAAEAAAAJAA0AAgAFAAEAAAAJAA4AAgAAAAAAAAAJAA8AAgABAAEAAAAJABAAAgAEAAAAAAAJABEAAgAAAAAAAAAJABIAAgADAAAAAAAJABMAAgABAAEAAAAKAAAAAgABAAEAAAAKAAEAAgACAAEAAAAKAAIAAgAAAAAAAAAKAAMAAgABAAEAAAAKAAQAAgAAAAEAAAAKAAUAAgAAAAAAAAAKAAYAAgABAAAAAAAKAAcAAgAAAAAAAAAKAAgAAgAEAAEAAAAKAAkAAgAAAAAAAAAKAAoAAgABAAAAAAAKAAsAAgACAAAAAAAKAAwAAgAEAAAAAAAKAA0AAgACAAAAAAAKAA4AAgABAAAAAAAKAA8AAgABAAAAAAAKABAAAgACAAEAAAAKABEAAgABAAAAAAAKABIAAgAFAAEAAAAKABMAAgABAAEAAAALAAAAAgABAAEAAAALAAEAAgAFAAEAAAALAAIAAgADAAAAAAALAAMAAgAEAAAAAAALAAQAAgAFAAAAAAALAAUAAgABAAEAAAALAAYAAgAFAAAAAAALAAcAAgAEAAEAAAALAAgAAgAAAAAAAAALAAkAAgAAAAEAAAALAAoAAgAEAAAAAAALAAsAAgAFAAEAAAALAAwAAgAFAAAAAAALAA0AAgADAAAAAAALAA4AAgABAAAAAAALAA8AAgADAAAAAAALABAAAgAFAAEAAAALABEAAgACAAAAAAALABIAAgACAAEAAAALABMAAgAFAAEAAAAMAAAAAgAAAAAAAAAMAAEAAgACAAEAAAAMAAIAAgACAAAAAAAMAAMAAgAAAAAAAAAMAAQAAgADAAAAAAAMAAUAAgAEAAEAAAAMAAYAAgABAAEAAAAMAAcAAgADAAEAAAAMAAgAAgACAAAAAAAMAAkAAgAEAAAAAAAMAAoAAgAEAAEAAAAMAAsAAgAEAAAAAAAMAAwAAgABAAAAAAAMAA0AAgACAAAAAAAMAA4AAgAEAAEAAAAMAA8AAgAEAAAAAAAMABAAAgAAAAEAAAAMABEAAgAEAAEAAAAMABIAAgAEAAAAAAAMABMAAgAAAAAAAAANAAAAAgADAAEAAAANAAEAAgAEAAEAAAANAAIAAgAEAAEAAAANAAMAAgADAAEAAAANAAQAAgAAAAEAAAANAAUAAgAEAAAAAAANAAYAAgACAAEAAAANAAcAAgACAAAAAAANAAgAAgAEAAAAAAANAAkAAgADAAEAAAANAAoAAgABAAAAAAANAAsAAgACAAEAAAANAAwAAgADAAAAAAANAA0AAgACAAAAAAANAA4AAgABAAEAAAANAA8AAgAFAAEAAAANABAAAgACAAEAAAANABEAAgAFAAAAAAANABIAAgADAAAAAAANABMAAgAFAAAAAAAOAAAAAgAFAAEAAAAOAAEAAgABAAEAAAAOAAIAAgAAAAEAAAAOAAMAAgAFAAEAAAAOAAQAAgAAAAAAAAAOAAUAAgACAAAAAAAOAAYAAgABAAAAAAAOAAcAAgAAAAAAAAAOAAgAAgACAAEAAAAOAAkAAgAAAAEAAAAOAAoAAgAEAAAAAAAOAAsAAgABAAEAAAAOAAwAAgAFAAEAAAAOAA0AAgACAAAAAAAOAA4AAgADAAAAAAAOAA8AAgAEAAEAAAAOABAAAgABAAEAAAAOABEAAgAFAAEAAAAOABIAAgAAAAEAAAAOABMAAgAEAAAAAAAPAAAAAgAAAAEAAAAPAAEAAgAEAAAAAAAPAAIAAgACAAAAAAAPAAMAAgACAAEAAAAPAAQAAgAEAAAAAAAPAAUAAgAEAAEAAAAPAAYAAgAFAAAAAAAPAAcAAgAAAAAAAAAPAAgAAgAFAAAAAAAPAAkAAgABAAEAAAAPAAoAAgACAAAAAAAPAAsAAgAFAAAAAAAPAAwAAgAAAAEAAAAPAA0AAgAFAAEAAAAPAA4AAgABAAEAAAAPAA8AAgACAAEAAAAPABAAAgACAAEAAAAPABEAAgADAAAAAAAPABIAAgACAAEAAAAPABMAAgAAAAAAAAAQAAAAAgAFAAEAAAAQAAEAAgAEAAEAAAAQAAIAAgADAAEAAAAQAAMAAgABAAAAAAAQAAQAAgAFAAEAAAAQAAUAAgACAAAAAAAQAAYAAgAAAAEAAAAQAAcAAgACAAAAAAAQAAgAAgAAAAAAAAAQAAkAAgAEAAEAAAAQAAoAAgAFAAAAAAAQAAsAAgABAAEAAAAQAAwAAgADAAAAAAAQAA0AAgAAAAEAAAAQAA4AAgAEAAAAAAAQAA8AAgACAAAAAAAQABAAAgACAAEAAAAQABEAAgADAAAAAAAQABIAAgABAAAAAAAQABMAAgAEAAAAAAARAAAAAgAAAAEAAAARAAEAAgACAAEAAAARAAIAAgACAAEAAAARAAMAAgABAAAAAAARAAQAAgAFAAEAAAARAAUAAgADAAAAAAARAAYAAgABAAAAAAARAAcAAgAEAAEAAAARAAgAAgABAAAAAAARAAkAAgADAAAAAAARAAoAAgAFAAEAAAARAAsAAgAFAAEAAAARAAwAAgAAAAAAAAARAA0AAgAFAAAAAAARAA4AAgAEAAAAAAARAA8AAgACAAAAAAARABAAAgAAAAEAAAARABEAAgADAAAAAAARABIAAgABAAAAAAARABMAAgAFAAAAAAASAAAAAgADAAEAAAASAAEAAgAAAAEAAAASAAIAAgABAAEAAAASAAMAAgAFAAEAAAASAAQAAgABAAEAAAASAAUAAgAEAAAAAAASAAYAAgAFAAAAAAASAAcAAgAFAAAAAAASAAgAAgABAAAAAAASAAkAAgACAAEAAAASAAoAAgACAAEAAAASAAsAAgAAAAEAAAASAAwAAgACAAEAAAASAA0AAgADAAAAAAASAA4AAgADAAEAAAASAA8AAgAFAAAAAAASABAAAgAFAAAAAAASABEAAgACAAEAAAASABIAAgABAAEAAAASABMAAgAEAAAAAAATAAAAAgADAAEAAAATAAEAAgAEAAAAAAATAAIAAgAAAAAAAAATAAMAAgAAAAAAAAATAAQAAgACAAEAAAATAAUAAgAFAAAAAAATAAYAAgAEAAEAAAATAAcAAgACAAAAAAATAAgAAgABAAAAAAATAAkAAgABAAEAAAATAAoAAgADAAAAAAATAAsAAgAFAAEAAAATAAwAAgADAAAAAAATAA0AAgAFAAAAAAATAA4AAgAFAAAAAAATAA8AAgADAAEAAAATABAAAgACAAAAAAATABEAAgADAAAAAAATABIAAgAFAAAAAAATABMAAgACAAEAAAAUAAAAAgAAAAAAAAAUAAEAAgADAAEAAAAUAAIAAgAEAAAAAAAUAAMAAgAAAAEAAAAUAAQAAgACAAEAAAAUAAUAAgAFAAEAAAAUAAYAAgABAAAAAAAUAAcAAgAAAAEAAAAUAAgAAgADAAEAAAAUAAkAAgACAAAAAAAUAAoAAgAFAAAAAAAUAAsAAgAEAAEAAAAUAAwAAgACAAEAAAAUAA0AAgAAAAEAAAAUAA4AAgABAAAAAAAUAA8AAgAAAAEAAAAUABAAAgAAAAEAAAAUABEAAgACAAEAAAAUABIAAgAFAAEAAAAUABMAAgACAAEAAAAVAAAAAgABAAEAAAAVAAEAAgAEAAAAAAAVAAIAAgAEAAAAAAAVAAMAAgACAAAAAAAVAAQAAgAEAAEAAAAVAAUAAgABAAAAAAAVAAYAAgAFAAAAAAAVAAcAAgADAAEAAAAVAAgAAgABAAEAAAAVAAkAAgACAAEAAAAVAAoAAgADAAAAAAAVAAsAAgAEAAEAAAAVAAwAAgAEAAAAAAAVAA0AAgACAAAAAAAVAA4AAgABAAAAAAAVAA8AAgACAAEAAAAVABAAAgADAAAAAAAVABEAAgABAAEAAAAVABIAAgAAAAEAAAAVABMAAgADAAAAAAAWAAAAAgABAAAAAAAWAAEAAgAAAAEAAAAWAAIAAgACAAAAAAAWAAMAAgAEAAEAAAAWAAQAAgAFAAAAAAAWAAUAAgACAAEAAAAWAAYAAgADAAEAAAAWAAcAAgABAAEAAAAWAAgAAgACAAEAAAAWAAkAAgAFAAAAAAAWAAoAAgAFAAAAAAAWAAsAAgADAAEAAAAWAAwAAgAFAAEAAAAWAA0AAgADAAEAAAAWAA4AAgAAAAEAAAAWAA8AAgAFAAAAAAAWABAAAgAAAAEAAAAWABEAAgAEAAAAAAAWABIAAgAEAAEAAAAWABMAAgACAAAAAAAXAAAAAgABAAEAAAAXAAEAAgABAAEAAAAXAAIAAgACAAAAAAAXAAMAAgAEAAAAAAAXAAQAAgAFAAAAAAAXAAUAAgAEAAEAAAAXAAYAAgAEAAAAAAAXAAcAAgABAAEAAAAXAAgAAgAEAAEAAAAXAAkAAgADAAEAAAAXAAoAAgAFAAEAAAAXAAsAAgAFAAEAAAAXAAwAAgABAAAAAAAXAA0AAgADAAEAAAAXAA4AAgADAAEAAAAXAA8AAgABAAAAAAAXABAAAgADAAAAAAAXABEAAgABAAAAAAAXABIAAgAAAAAAAAAXABMAAgADAAEAAAAYAAAAAgADAAAAAAAYAAEAAgAFAAAAAAAYAAIAAgADAAEAAAAYAAMAAgAFAAEAAAAYAAQAAgAFAAAAAAAYAAUAAgAFAAEAAAAYAAYAAgAEAAAAAAAYAAcAAgAAAAEAAAAYAAgAAgACAAAAAAAYAAkAAgAEAAEAAAAYAAoAAgABAAEAAAAYAAsAAgACAAEAAAAYAAwAAgAAAAAAAAAYAA0AAgACAAEAAAAYAA4AAgABAAAAAAAYAA8AAgADAAEAAAAYABAAAgAAAAEAAAAYABEAAgAEAAEAAAAYABIAAgADAAAAAAAYABMAAgAFAAEAAAAZAAAAAgAFAAAAAAAZAAEAAgAEAAEAAAAZAAIAAgAAAAAAAAAZAAMAAgAFAAEAAAAZAAQAAgADAAAAAAAZAAUAAgAEAAEAAAAZAAYAAgACAAEAAAAZAAcAAgACAAAAAAAZAAgAAgACAAEAAAAZAAkAAgAEAAEAAAAZAAoAAgABAAEAAAAZAAsAAgAEAAEAAAAZAAwAAgABAAAAAAAZAA0AAgABAAAAAAAZAA4AAgAAAAEAAAAZAA8AAgADAAAAAAAZABAAAgAFAAAAAAAZABEAAgAFAAAAAAAZABIAAgAEAAEAAAAZABMAAgAFAAAAAAAaAAAAAgACAAEAAAAaAAEAAgAEAAAAAAAaAAIAAgAEAAEAAAAaAAMAAgAEAAAAAAAaAAQAAgAAAAAAAAAaAAUAAgAAAAAAAAAaAAYAAgAEAAAAAAAaAAcAAgAEAAAAAAAaAAgAAgADAAEAAAAaAAkAAgADAAAAAAAaAAoAAgACAAEAAAAaAAsAAgADAAAAAAAaAAwAAgAEAAAAAAAaAA0AAgACAAAAAAAaAA4AAgABAAEAAAAaAA8AAgABAAAAAAAaABAAAgAAAAEAAAAaABEAAgABAAAAAAAaABIAAgADAAAAAAAaABMAAgAAAAAAAAAbAAAAAgAAAAAAAAAbAAEAAgAEAAEAAAAbAAIAAgAAAAAAAAAbAAMAAgACAAEAAAAbAAQAAgAEAAAAAAAbAAUAAgAAAAEAAAAbAAYAAgACAAAAAAAbAAcAAgABAAEAAAAbAAgAAgAAAAAAAAAbAAkAAgAAAAEAAAAbAAoAAgAAAAEAAAAbAAsAAgADAAAAAAAbAAwAAgAEAAEAAAAbAA0AAgACAAAAAAAbAA4AAgAFAAAAAAAbAA8AAgABAAEAAAAbABAAAgABAAEAAAAbABEAAgAAAAEAAAAbABIAAgAFAAAAAAAbABMAAgADAAEAAAAcAAAAAgAAAAEAAAAcAAEAAgABAAEAAAAcAAIAAgACAAEAAAAcAAMAAgABAAAAAAAcAAQAAgABAAAAAAAcAAUAAgADAAEAAAAcAAYAAgAEAAEAAAAcAAcAAgAAAAEAAAAcAAgAAgAFAAEAAAAcAAkAAgABAAAAAAAcAAoAAgAFAAAAAAAcAAsAAgABAAAAAAAcAAwAAgAFAAEAAAAcAA0AAgAEAAEAAAAcAA4AAgAEAAEAAAAcAA8AAgADAAAAAAAcABAAAgAAAAAAAAAcABEAAgACAAEAAAAcABIAAgACAAAAAAAcABMAAgAAAAEAAAAdAAAAAgAEAAAAAAAdAAEAAgAFAAEAAAAdAAIAAgAAAAEAAAAdAAMAAgAFAAAAAAAdAAQAAgAAAAEAAAAdAAUAAgAEAAAAAAAdAAYAAgAEAAEAAAAdAAcAAgAEAAEAAAAdAAgAAgADAAEAAAAdAAkAAgADAAEAAAAdAAoAAgACAAEAAAAdAAsAAgABAAAAAAAdAAwAAgADAAEAAAAdAA0AAgAAAAEAAAAdAA4AAgAEAAAAAAAdAA8AAgACAAAAAAAdABAAAgAAAAEAAAAdABEAAgACAAEAAAAdABIAAgAEAAAAAAAdABMAAgACAAAAAAAeAAAAAgADAAAAAAAeAAEAAgACAAEAAAAeAAIAAgAFAAEAAAAeAAMAAgAAAAEAAAAeAAQAAgAFAAEAAAAeAAUAAgABAAAAAAAeAAYAAgAFAAAAAAAeAAcAAgADAAAAAAAeAAgAAgABAAEAAAAeAAkAAgACAAAAAAAeAAoAAgACAAAAAAAeAAsAAgADAAEAAAAeAAwAAgAFAAEAAAAeAA0AAgABAAAAAAAeAA4AAgACAAAAAAAeAA8AAgAAAAEAAAAeABAAAgAFAAAAAAAeABEAAgABAAEAAAAeABIAAgABAAEAAAAeABMAAgAEAAAAAAAfAAAAAgACAAEAAAAfAAEAAgAEAAAAAAAfAAIAAgAFAAEAAAAfAAMAAgAEAAAAAAAfAAQAAgACAAEAAAAfAAUAAgAEAAAAAAAfAAYAAgADAAEAAAAfAAcAAgAAAAEAAAAfAAgAAgABAAEAAAAfAAkAAgAEAAEAAAAfAAoAAgAAAAEAAAAfAAsAAgADAAAAAAAfAAwAAgABAAEAAAAfAA0AAgABAAEAAAAfAA4AAgAAAAAAAAAfAA8AAgADAAEAAAAfABAAAgABAAAAAAAfABEAAgACAAEAAAAfABIAAgABAAEAAAAfABMAAgAAAAAAAAAgAAAAAgADAAAAAAAgAAEAAgAFAAEAAAAgAAIAAgAEAAAAAAAgAAMAAgAEAAAAAAAgAAQAAgAEAAAAAAAgAAUAAgABAAAAAAAgAAYAAgACAAAAAAAgAAcAAgAFAAAAAAAgAAgAAgACAAEAAAAgAAkAAgACAAAAAAAgAAoAAgAFAAEAAAAgAAsAAgAAAAAAAAAgAAwAAgAFAAEAAAAgAA0AAgAFAAAAAAAgAA4AAgACAAAAAAAgAA8AAgAAAAEAAAAgABAAAgAFAAEAAAAgABEAAgAEAAEAAAAgABIAAgACAAEAAAAgABMAAgACAAAAAAAhAAAAAgABAAAAAAAhAAEAAgAAAAEAAAAhAAIAAgABAAEAAAAhAAMAAgAFAAEAAAAhAAQAAgAFAAAAAAAhAAUAAgAAAAAAAAAhAAYAAgAFAAEAAAAhAAcAAgABAAEAAAAhAAgAAgAEAAEAAAAhAAkAAgAFAAAAAAAhAAoAAgAAAAEAAAAhAAsAAgACAAEAAAAhAAwAAgAFAAAAAAAhAA0AAgABAAEAAAAhAA4AAgADAAEAAAAhAA8AAgAEAAEAAAAhABAAAgADAAEAAAAhABEAAgAFAAEAAAAhABIAAgABAAEAAAAhABMAAgAEAAAAAAAiAAAAAgACAAAAAAAiAAEAAgACAAEAAAAiAAIAAgACAAEAAAAiAAMAAgADAAAAAAAiAAQAAgAEAAEAAAAiAAUAAgADAAAAAAAiAAYAAgACAAEAAAAiAAcAAgAEAAAAAAAiAAgAAgAFAAAAAAAiAAkAAgAFAAAAAAAiAAoAAgAEAAAAAAAiAAsAAgADAAEAAAAiAAwAAgAFAAEAAAAiAA0AAgAEAAAAAAAiAA4AAgADAAEAAAAiAA8AAgAAAAEAAAAiABAAAgACAAAAAAAiABEAAgABAAAAAAAiABIAAgABAAEAAAAiABMAAgAAAAEAAAAjAAAAAgACAAEAAAAjAAEAAgAAAAAAAAAjAAIAAgAAAAEAAAAjAAMAAgABAAEAAAAjAAQAAgACAAEAAAAjAAUAAgABAAEAAAAjAAYAAgAAAAAAAAAjAAcAAgAAAAEAAAAjAAgAAgADAAEAAAAjAAkAAgAFAAEAAAAjAAoAAgAEAAAAAAAjAAsAAgAFAAAAAAAjAAwAAgABAAEAAAAjAA0AAgABAAAAAAAjAA4AAgACAAEAAAAjAA8AAgACAAEAAAAjABAAAgADAAEAAAAjABEAAgADAAEAAAAjABIAAgADAAEAAAAjABMAAgACAAAAAAAAABQAAgABAAAAAAABABQAAgACAAAAAAACABQAAgABAAAAAAADABQAAgACAAAAAAAEABQAAgADAAEAAAAFABQAAgABAAEAAAAGABQAAgACAAAAAAAHABQAAgACAAAAAAAIABQAAgAFAAAAAAAJABQAAgACAAAAAAAKABQAAgAFAAAAAAALABQAAgACAAAAAAAMABQAAgAEAAAAAAANABQAAgADAAAAAAAOABQAAgACAAEAAAAPABQAAgADAAEAAAAQABQAAgAEAAEAAAARABQAAgACAAEAAAASABQAAgABAAAAAAATABQAAgADAAAAAAAUABQAAgADAAEAAAAVABQAAgAEAAEAAAAWABQAAgACAAAAAAAXABQAAgAFAAAAAAAYABQAAgAEAAAAAAAZABQAAgAEAAAAAAAaABQAAgAEAAAAAAAbABQAAgAAAAEAAAAcABQAAgADAAAAAAAdABQAAgAEAAEAAAAeABQAAgACAAEAAAAfABQAAgAEAAAAAAAgABQAAgABAAEAAAAhABQAAgACAAEAAAAiABQAAgABAAAAAAAjABQAAgAEAAEAAAA=") +tile_set = ExtResource("1_3jghe") +collision_enabled = false +navigation_enabled = false + +[node name="PathLayer" type="TileMapLayer" parent="."] +scale = Vector2(2, 2) +tile_map_data = PackedByteArray("AAAGAAYAAwAAAAEAAAAGAAcAAwAAAAEAAAAGAAgAAwAAAAEAAAAGAAkAAwAAAAEAAAAGAAoAAwAAAAEAAAAGAAsAAwAAAAEAAAAGAAwAAwAAAAEAAAAGAA0AAwAAAAEAAAAGAA4AAwAAAAEAAAAGAA8AAwAAAAEAAAAGABAAAwABAAIAAAAHAAgAAwACAAMAAAAHABAAAwACAAMAAAAIAAgAAwACAAMAAAAIABAAAwACAAMAAAAJAAkAAwAAAAEAAAAJAAoAAwAAAAEAAAAJAAsAAwAAAAEAAAAJAAwAAwAAAAEAAAAJAA0AAwAAAAEAAAAJAA4AAwAAAAEAAAAJAA8AAwAAAAEAAAAKAAgAAwACAAMAAAAKABAAAwACAAMAAAALAAgAAwACAAMAAAALABAAAwACAAMAAAAMAAgAAwACAAMAAAAMABAAAwACAAMAAAANAAgAAwACAAMAAAANABAAAwACAAMAAAAOAAgAAwACAAMAAAAOABAAAwACAAMAAAAPAAgAAwACAAMAAAAPABAAAwACAAMAAAAQAAgAAwACAAMAAAAQABAAAwACAAMAAAARAAgAAwACAAMAAAARAA4AAwABAAEAAAARAA8AAwAAAAEAAAARABAAAwACAAIAAAASAA4AAwACAAMAAAATAAgAAwACAAMAAAATAA4AAwACAAMAAAAUAAgAAwACAAMAAAAUAA4AAwACAAMAAAAVAAgAAwACAAMAAAAVAA4AAwACAAMAAAAWAAgAAwACAAMAAAAWAA4AAwACAAMAAAAXAAgAAwACAAMAAAAXAA4AAwACAAMAAAAYAA4AAwACAAMAAAAZAAgAAwACAAMAAAAZAA4AAwACAAMAAAAaAAgAAwACAAMAAAAaAA4AAwACAAMAAAAbAAgAAwACAAMAAAAbAA4AAwACAAMAAAAcAAgAAwACAAMAAAAcAA4AAwACAAMAAAAeAAYAAwAAAAEAAAAeAAcAAwAAAAEAAAAeAAkAAwAAAAEAAAAeAAoAAwAAAAEAAAAeAAsAAwAAAAEAAAAeAAwAAwAAAAEAAAAeAA0AAwAAAAEAAAAeAA4AAwACAAIAAAAdAAgAAwACAAMAAAAdAA4AAwACAAMAAAASAAgAAwACAAMAAAAGAAMAAwABAAEAAAAHAAMAAwACAAMAAAAIAAMAAwACAAMAAAAJAAMAAwACAAMAAAAKAAMAAwACAAMAAAALAAMAAwACAAMAAAAMAAMAAwACAAMAAAANAAMAAwACAAMAAAAOAAMAAwACAAMAAAAQAAMAAwACAAMAAAARAAMAAwACAAMAAAASAAMAAwACAAMAAAATAAMAAwACAAMAAAAUAAMAAwACAAMAAAAVAAMAAwACAAMAAAAWAAMAAwACAAMAAAAXAAMAAwACAAMAAAAYAAMAAwACAAMAAAAZAAMAAwACAAMAAAAaAAMAAwACAAMAAAAbAAMAAwACAAMAAAAcAAMAAwACAAMAAAAdAAMAAwACAAMAAAAeAAMAAwACAAEAAAAQAAUAAwACAAMAAAARAAUAAwACAAMAAAASAAUAAwACAAMAAAATAAUAAwACAAMAAAAUAAUAAwACAAMAAAAVAAUAAwACAAMAAAAWAAUAAwACAAMAAAAXAAUAAwACAAMAAAAPAAQAAwAAAAEAAAAYAAYAAwAAAAEAAAAYAAcAAwAAAAEAAAAYAAUAAwACAAEAAAAPAAUAAwABAAIAAAAGAAQAAwAAAAEAAAAGAAUAAwAAAAEAAAAeAAQAAwAAAAEAAAAeAAUAAwAAAAEAAAA=") +tile_set = ExtResource("1_3jghe") + +[node name="DataLayer" type="TileMapLayer" parent="."] +scale = Vector2(2, 2) +tile_map_data = PackedByteArray("AAAGAAYAAQAAAAAAAAAGAAcAAQABAAAAAAAGAAgAAQAAAAEAAAAGAAkAAQABAAAAAAAGAAoAAQAAAAEAAAAGAAsAAQAAAAAAAAAGAAwAAQAAAAAAAAAGAA0AAQABAAAAAAAGAA4AAQAAAAEAAAAGAA8AAQABAAAAAAAGABAAAQAAAAEAAAARAA4AAQAAAAEAAAASAA4AAQAAAAAAAAATAA4AAQAEAAAAAAAUAA4AAQAAAAEAAAAWAA4AAQAEAAAAAAAXAA4AAQAAAAEAAAAZAA4AAQAEAAAAAAAcAA4AAQAAAAAAAAARAA8AAQADAAAAAAARABAAAQAAAAEAAAAHABAAAQAAAAAAAAAIABAAAQAEAAAAAAAJABAAAQAAAAEAAAAKABAAAQAAAAAAAAAMABAAAQAEAAAAAAANABAAAQAAAAEAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAAJAAgAAQAAAAEAAAAJAAkAAQAAAAAAAAAJAA8AAQABAAAAAAAHAAgAAQACAAAAAAAIAAgAAQAAAAAAAAAKAAgAAQACAAAAAAALAAgAAQAAAAAAAAAMAAgAAQAAAAEAAAANAAgAAQACAAAAAAAOAAgAAQAAAAAAAAAPAAgAAQAAAAEAAAAQAAgAAQACAAAAAAARAAgAAQAAAAAAAAASAAgAAQAAAAEAAAATAAgAAQACAAAAAAAUAAgAAQAAAAAAAAAVAAgAAQAAAAEAAAAWAAgAAQACAAAAAAAXAAgAAQAAAAAAAAAYAAgAAQAAAAEAAAAZAAgAAQACAAAAAAAaAAgAAQAAAAAAAAAbAAgAAQAAAAEAAAAcAAgAAQACAAAAAAAeAAcAAQAAAAAAAAAeAAgAAQAAAAEAAAAeAAkAAQADAAAAAAAeAAoAAQAAAAAAAAAeAAsAAQAAAAEAAAAeAAwAAQADAAAAAAAeAA0AAQAAAAAAAAAeAA4AAQAAAAEAAAAdAA4AAQAEAAAAAAAdAAgAAQAAAAAAAAAVAA4AAQAAAAAAAAAYAA4AAQAAAAAAAAAaAA4AAQAAAAEAAAAbAA4AAQAAAAAAAAALABAAAQAAAAAAAAAOABAAAQAAAAAAAAAJAAsAAQAAAAEAAAAJAAwAAQABAAAAAAAJAA0AAQAAAAEAAAAJAA4AAQAAAAAAAAAJAAoAAQABAAAAAAAGAAMAAQAAAAEAAAAHAAMAAQACAAAAAAAIAAMAAQAAAAAAAAAJAAMAAQAAAAEAAAAKAAMAAQACAAAAAAALAAMAAQAAAAAAAAAMAAMAAQAAAAEAAAANAAMAAQACAAAAAAAOAAMAAQAAAAAAAAAPAAMAAQAAAAEAAAAQAAMAAQACAAAAAAARAAMAAQAAAAAAAAASAAMAAQAAAAEAAAATAAMAAQACAAAAAAAUAAMAAQAAAAAAAAAVAAMAAQAAAAEAAAAWAAMAAQACAAAAAAAXAAMAAQAAAAAAAAAYAAMAAQAAAAEAAAAZAAMAAQACAAAAAAAaAAMAAQAAAAAAAAAbAAMAAQAAAAEAAAAcAAMAAQACAAAAAAAdAAMAAQAAAAAAAAAeAAMAAQAAAAEAAAAGAAQAAQABAAAAAAAGAAUAAQAAAAEAAAAeAAQAAQADAAAAAAAeAAUAAQAAAAEAAAAeAAYAAQADAAAAAAAPAAQAAQADAAAAAAAPAAUAAQAAAAEAAAAQAAUAAQACAAAAAAARAAUAAQAAAAAAAAASAAUAAQAAAAAAAAATAAUAAQAAAAAAAAAUAAUAAQAAAAAAAAAVAAUAAQAAAAAAAAAWAAUAAQAAAAAAAAAXAAUAAQAAAAAAAAAYAAUAAQAAAAEAAAAYAAYAAQADAAAAAAAYAAcAAQAAAAAAAAA=") +tile_set = ExtResource("1_3jghe") + +[node name="TestDataLayer" type="TileMapLayer" parent="."] +visible = false +scale = Vector2(2, 2) +tile_map_data = PackedByteArray("AAAKABAAAQAEAAAAAAALABAAAQAAAAAAAAAMABAAAQAAAAAAAAANABAAAQAAAAAAAAAOABAAAQAAAAAAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAARABAAAQAAAAEAAAAJABAAAQAAAAEAAAANAA4AAQABAAAAAAANAA8AAQAAAAAAAAANAA0AAQAAAAEAAAAOAA0AAQACAAAAAAAPAA0AAQAAAAAAAAAQAA0AAQAAAAEAAAA=") +tile_set = ExtResource("1_3jghe") + +[node name="NavigationGraph" type="Node2D" parent="."] +script = ExtResource("3_ww84c") + +[node name="Player" type="CharacterBody2D" parent="."] +position = Vector2(310, 140) +scale = Vector2(0.640001, 0.640001) +collision_mask = 3 +script = ExtResource("4_djnau") +metadata/_edit_group_ = true + +[node name="Icon" type="Sprite2D" parent="Player"] +scale = Vector2(0.4, 0.4) +texture = ExtResource("5_3opuj") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +shape = SubResource("CapsuleShape2D_cgpao") diff --git a/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn b/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn index a064646..31f5f10 100644 --- a/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn +++ b/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn @@ -1,8 +1,14 @@ -[gd_scene load_steps=4 format=4 uid="uid://ddlksorhs8rls"] +[gd_scene load_steps=7 format=4 uid="uid://ddlksorhs8rls"] [ext_resource type="TileSet" uid="uid://cm6wi7fjgfk56" path="res://scenes/mario-party/MarioPartyTiles.tres" id="1_3jghe"] [ext_resource type="Script" path="res://scenes/mario-party/MarioPartyManagement.gd" id="1_r0jft"] [ext_resource type="Script" path="res://scenes/mario-party/MPNavigationGraph.gd" id="3_ww84c"] +[ext_resource type="Script" path="res://scenes/mario-party/PlayerController.gd" id="4_djnau"] +[ext_resource type="Texture2D" uid="uid://c53ftc05so8rx" path="res://icon.svg" id="5_3opuj"] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_cgpao"] +radius = 24.9999 +height = 49.9999 [node name="MarioParty" type="Node2D"] script = ExtResource("1_r0jft") @@ -16,19 +22,43 @@ navigation_enabled = false [node name="PathLayer" type="TileMapLayer" parent="."] scale = Vector2(2, 2) -tile_map_data = PackedByteArray("AAAGAAYAAwAAAAEAAAAGAAcAAwAAAAEAAAAGAAgAAwAAAAEAAAAGAAkAAwAAAAEAAAAGAAoAAwAAAAEAAAAGAAsAAwAAAAEAAAAGAAwAAwAAAAEAAAAGAA0AAwAAAAEAAAAGAA4AAwAAAAEAAAAGAA8AAwAAAAEAAAAGABAAAwABAAIAAAAHAAgAAwACAAMAAAAHABAAAwACAAMAAAAIAAgAAwACAAMAAAAIABAAAwACAAMAAAAJAAkAAwAAAAEAAAAJAAoAAwAAAAEAAAAJAAsAAwAAAAEAAAAJAAwAAwAAAAEAAAAJAA0AAwAAAAEAAAAJAA4AAwAAAAEAAAAJAA8AAwAAAAEAAAAKAAgAAwACAAMAAAAKABAAAwACAAMAAAALAAgAAwACAAMAAAALABAAAwACAAMAAAAMAAgAAwACAAMAAAAMABAAAwACAAMAAAANAAgAAwACAAMAAAANABAAAwACAAMAAAAOAAgAAwACAAMAAAAOABAAAwACAAMAAAAPAAgAAwACAAMAAAAPABAAAwACAAMAAAAQAAgAAwACAAMAAAAQABAAAwACAAMAAAARAAgAAwACAAMAAAARAA4AAwABAAEAAAARAA8AAwAAAAEAAAARABAAAwACAAIAAAASAA4AAwACAAMAAAATAAgAAwACAAMAAAATAA4AAwACAAMAAAAUAAgAAwACAAMAAAAUAA4AAwACAAMAAAAVAAgAAwACAAMAAAAVAA4AAwACAAMAAAAWAAgAAwACAAMAAAAWAA4AAwACAAMAAAAXAAgAAwACAAMAAAAXAA4AAwACAAMAAAAYAA4AAwACAAMAAAAZAAgAAwACAAMAAAAZAA4AAwACAAMAAAAaAAgAAwACAAMAAAAaAA4AAwACAAMAAAAbAAgAAwACAAMAAAAbAA4AAwACAAMAAAAcAAgAAwACAAMAAAAcAA4AAwACAAMAAAAeAAYAAwAAAAEAAAAeAAcAAwAAAAEAAAAeAAkAAwAAAAEAAAAeAAoAAwAAAAEAAAAeAAsAAwAAAAEAAAAeAAwAAwAAAAEAAAAeAA0AAwAAAAEAAAAeAA4AAwACAAIAAAAdAAgAAwACAAMAAAAdAA4AAwACAAMAAAASAAgAAwACAAMAAAAGAAMAAwABAAEAAAAHAAMAAwACAAMAAAAIAAMAAwACAAMAAAAJAAMAAwACAAMAAAAKAAMAAwACAAMAAAALAAMAAwACAAMAAAAMAAMAAwACAAMAAAANAAMAAwACAAMAAAAOAAMAAwACAAMAAAAQAAMAAwACAAMAAAARAAMAAwACAAMAAAASAAMAAwACAAMAAAATAAMAAwACAAMAAAAUAAMAAwACAAMAAAAVAAMAAwACAAMAAAAWAAMAAwACAAMAAAAXAAMAAwACAAMAAAAYAAMAAwACAAMAAAAZAAMAAwACAAMAAAAaAAMAAwACAAMAAAAbAAMAAwACAAMAAAAcAAMAAwACAAMAAAAdAAMAAwACAAMAAAAeAAMAAwACAAEAAAAQAAUAAwACAAMAAAARAAUAAwACAAMAAAASAAUAAwACAAMAAAATAAUAAwACAAMAAAAUAAUAAwACAAMAAAAVAAUAAwACAAMAAAAWAAUAAwACAAMAAAAXAAUAAwACAAMAAAAPAAQAAwAAAAEAAAAYAAYAAwAAAAEAAAAYAAcAAwAAAAEAAAAYAAUAAwACAAEAAAAPAAUAAwABAAIAAAAGAAQAAwAAAAEAAAAGAAUAAwAAAAEAAAAeAAQAAwAAAAEAAAAeAAUAAwAAAAEAAAA=") +tile_map_data = PackedByteArray("AAAGAAYAAwAAAAEAAAAGAAcAAwAAAAEAAAAGAAgAAwAAAAEAAAAGAAkAAwAAAAEAAAAGAAoAAwAAAAEAAAAGAAsAAwAAAAEAAAAGAAwAAwAAAAEAAAAGAA0AAwAAAAEAAAAGAA4AAwAAAAEAAAAGAA8AAwAAAAEAAAAGABAAAwABAAIAAAAHAAgAAwACAAMAAAAHABAAAwACAAMAAAAIAAgAAwACAAMAAAAIABAAAwACAAMAAAAJAAkAAwAAAAEAAAAJAAoAAwAAAAEAAAAJAAsAAwAAAAEAAAAJAAwAAwAAAAEAAAAJAA0AAwAAAAEAAAAJAA4AAwAAAAEAAAAJAA8AAwAAAAEAAAAKAAgAAwACAAMAAAAKABAAAwACAAMAAAALAAgAAwACAAMAAAALABAAAwACAAMAAAAMAAgAAwACAAMAAAAMABAAAwACAAMAAAANAAgAAwACAAMAAAANABAAAwACAAMAAAAOAAgAAwACAAMAAAAOABAAAwACAAMAAAAPAAgAAwACAAMAAAAPABAAAwACAAMAAAAQAAgAAwACAAMAAAAQABAAAwACAAMAAAARAAgAAwACAAMAAAARAA4AAwAAAAEAAAARAA8AAwAAAAEAAAARABAAAwACAAIAAAASAA4AAwACAAMAAAATAAgAAwACAAMAAAATAA4AAwACAAMAAAAUAAgAAwACAAMAAAAUAA4AAwACAAMAAAAVAAgAAwACAAMAAAAVAA4AAwACAAMAAAAWAAgAAwACAAMAAAAWAA4AAwACAAMAAAAXAAgAAwACAAMAAAAXAA4AAwACAAMAAAAYAA4AAwACAAMAAAAZAAgAAwACAAMAAAAZAA4AAwACAAMAAAAaAAgAAwACAAMAAAAaAA4AAwACAAMAAAAbAAgAAwACAAMAAAAbAA4AAwACAAMAAAAcAAgAAwACAAMAAAAcAA4AAwACAAMAAAAeAAYAAwAAAAEAAAAeAAcAAwAAAAEAAAAeAAkAAwAAAAEAAAAeAAoAAwAAAAEAAAAeAAsAAwAAAAEAAAAeAAwAAwAAAAEAAAAeAA0AAwAAAAEAAAAeAA4AAwACAAIAAAAdAAgAAwACAAMAAAAdAA4AAwACAAMAAAASAAgAAwACAAMAAAAGAAMAAwABAAEAAAAHAAMAAwACAAMAAAAIAAMAAwACAAMAAAAJAAMAAwACAAMAAAAKAAMAAwACAAMAAAALAAMAAwACAAMAAAAMAAMAAwACAAMAAAANAAMAAwACAAMAAAAOAAMAAwACAAMAAAAQAAMAAwACAAMAAAARAAMAAwACAAMAAAASAAMAAwACAAMAAAATAAMAAwACAAMAAAAUAAMAAwACAAMAAAAVAAMAAwACAAMAAAAWAAMAAwACAAMAAAAXAAMAAwACAAMAAAAYAAMAAwACAAMAAAAZAAMAAwACAAMAAAAaAAMAAwACAAMAAAAbAAMAAwACAAMAAAAcAAMAAwACAAMAAAAdAAMAAwACAAMAAAAeAAMAAwACAAEAAAAQAAUAAwACAAMAAAARAAUAAwACAAMAAAASAAUAAwACAAMAAAATAAUAAwACAAMAAAAUAAUAAwACAAMAAAAVAAUAAwACAAMAAAAWAAUAAwACAAMAAAAXAAUAAwACAAMAAAAPAAQAAwAAAAEAAAAYAAYAAwAAAAEAAAAYAAcAAwAAAAEAAAAYAAUAAwACAAEAAAAPAAUAAwABAAIAAAAGAAQAAwAAAAEAAAAGAAUAAwAAAAEAAAAeAAQAAwAAAAEAAAAeAAUAAwAAAAEAAAAPAAkAAwAAAAEAAAAPAAoAAwAAAAEAAAANAAwAAwAAAAEAAAANAA0AAwAAAAEAAAANAA4AAwAAAAEAAAANAA8AAwAAAAEAAAAOAAsAAwACAAMAAAANAAsAAwABAAEAAAAPAAsAAwACAAIAAAAJAAgAAwACAAMAAAAYAAgAAwACAAMAAAAPAAMAAwACAAMAAAAJABAAAwACAAMAAAAeAAgAAwAAAAEAAAAVAAkAAwAAAAEAAAAVAAoAAwAAAAEAAAASAAsAAwACAAMAAAATAAsAAwACAAMAAAAUAAsAAwACAAMAAAAVAAsAAwACAAMAAAAWAAsAAwACAAMAAAAXAAsAAwACAAMAAAAYAAsAAwACAAMAAAAZAAsAAwACAAMAAAARAAwAAwAAAAEAAAARAA0AAwAAAAEAAAAaAAwAAwAAAAEAAAAaAA0AAwAAAAEAAAAaAAsAAwACAAEAAAARAAsAAwABAAEAAAA=") tile_set = ExtResource("1_3jghe") [node name="DataLayer" type="TileMapLayer" parent="."] visible = false scale = Vector2(2, 2) -tile_map_data = PackedByteArray("AAAGAAYAAQAAAAAAAAAGAAcAAQABAAAAAAAGAAgAAQAAAAEAAAAGAAkAAQABAAAAAAAGAAoAAQAAAAEAAAAGAAsAAQAAAAAAAAAGAAwAAQAAAAAAAAAGAA0AAQABAAAAAAAGAA4AAQAAAAEAAAAGAA8AAQABAAAAAAAGABAAAQAAAAEAAAARAA4AAQAAAAEAAAASAA4AAQAAAAAAAAATAA4AAQAEAAAAAAAUAA4AAQAAAAEAAAAWAA4AAQAEAAAAAAAXAA4AAQAAAAEAAAAZAA4AAQAEAAAAAAAcAA4AAQAAAAAAAAARAA8AAQADAAAAAAARABAAAQAAAAEAAAAHABAAAQAAAAAAAAAIABAAAQAEAAAAAAAJABAAAQAAAAEAAAAKABAAAQAAAAAAAAAMABAAAQAEAAAAAAANABAAAQAAAAEAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAAJAAgAAQAAAAEAAAAJAAkAAQAAAAAAAAAJAA8AAQABAAAAAAAHAAgAAQACAAAAAAAIAAgAAQAAAAAAAAAKAAgAAQACAAAAAAALAAgAAQAAAAAAAAAMAAgAAQAAAAEAAAANAAgAAQACAAAAAAAOAAgAAQAAAAAAAAAPAAgAAQAAAAEAAAAQAAgAAQACAAAAAAARAAgAAQAAAAAAAAASAAgAAQAAAAEAAAATAAgAAQACAAAAAAAUAAgAAQAAAAAAAAAVAAgAAQAAAAEAAAAWAAgAAQACAAAAAAAXAAgAAQAAAAAAAAAYAAgAAQAAAAEAAAAZAAgAAQACAAAAAAAaAAgAAQAAAAAAAAAbAAgAAQAAAAEAAAAcAAgAAQACAAAAAAAeAAcAAQAAAAAAAAAeAAgAAQAAAAEAAAAeAAkAAQADAAAAAAAeAAoAAQAAAAAAAAAeAAsAAQAAAAEAAAAeAAwAAQADAAAAAAAeAA0AAQAAAAAAAAAeAA4AAQAAAAEAAAAdAA4AAQAEAAAAAAAdAAgAAQAAAAAAAAAVAA4AAQAAAAAAAAAYAA4AAQAAAAAAAAAaAA4AAQAAAAEAAAAbAA4AAQAAAAAAAAALABAAAQAAAAAAAAAOABAAAQAAAAAAAAAJAAsAAQAAAAEAAAAJAAwAAQABAAAAAAAJAA0AAQAAAAEAAAAJAA4AAQAAAAAAAAAJAAoAAQABAAAAAAAGAAMAAQAAAAEAAAAHAAMAAQACAAAAAAAIAAMAAQAAAAAAAAAJAAMAAQAAAAEAAAAKAAMAAQACAAAAAAALAAMAAQAAAAAAAAAMAAMAAQAAAAEAAAANAAMAAQACAAAAAAAOAAMAAQAAAAAAAAAPAAMAAQAAAAEAAAAQAAMAAQACAAAAAAARAAMAAQAAAAAAAAASAAMAAQAAAAEAAAATAAMAAQACAAAAAAAUAAMAAQAAAAAAAAAVAAMAAQAAAAEAAAAWAAMAAQACAAAAAAAXAAMAAQAAAAAAAAAYAAMAAQAAAAEAAAAZAAMAAQACAAAAAAAaAAMAAQAAAAAAAAAbAAMAAQAAAAEAAAAcAAMAAQACAAAAAAAdAAMAAQAAAAAAAAAeAAMAAQAAAAEAAAAGAAQAAQABAAAAAAAGAAUAAQAAAAEAAAAeAAQAAQADAAAAAAAeAAUAAQAAAAEAAAAeAAYAAQADAAAAAAAPAAQAAQADAAAAAAAPAAUAAQAAAAEAAAAQAAUAAQACAAAAAAARAAUAAQAAAAAAAAASAAUAAQAAAAAAAAATAAUAAQAAAAAAAAAUAAUAAQAAAAAAAAAVAAUAAQAAAAAAAAAWAAUAAQAAAAAAAAAXAAUAAQAAAAAAAAAYAAUAAQAAAAEAAAAYAAYAAQADAAAAAAAYAAcAAQAAAAAAAAA=") +tile_map_data = PackedByteArray("AAAGAAYAAQAAAAAAAAAGAAcAAQABAAAAAAAGAAgAAQAAAAEAAAAGAAkAAQABAAAAAAAGAAoAAQAAAAEAAAAGAAsAAQAAAAAAAAAGAAwAAQAAAAAAAAAGAA0AAQABAAAAAAAGAA4AAQAAAAEAAAAGAA8AAQABAAAAAAAGABAAAQAAAAEAAAARAA4AAQAAAAEAAAASAA4AAQAAAAAAAAATAA4AAQAEAAAAAAAUAA4AAQAAAAEAAAAWAA4AAQAEAAAAAAAXAA4AAQAAAAEAAAAZAA4AAQAEAAAAAAAcAA4AAQAAAAAAAAARAA8AAQADAAAAAAARABAAAQAAAAEAAAAHABAAAQAAAAAAAAAIABAAAQAEAAAAAAAJABAAAQAAAAEAAAAKABAAAQAAAAAAAAAMABAAAQAEAAAAAAANABAAAQAAAAEAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAAJAAgAAQAAAAEAAAAJAAkAAQAAAAAAAAAJAA8AAQABAAAAAAAHAAgAAQACAAAAAAAIAAgAAQAAAAAAAAAKAAgAAQACAAAAAAALAAgAAQAAAAAAAAAMAAgAAQAAAAEAAAANAAgAAQACAAAAAAAOAAgAAQAAAAAAAAAPAAgAAQAAAAEAAAAQAAgAAQACAAAAAAARAAgAAQAAAAAAAAASAAgAAQAAAAEAAAATAAgAAQACAAAAAAAUAAgAAQAAAAAAAAAVAAgAAQAAAAEAAAAWAAgAAQACAAAAAAAXAAgAAQAAAAAAAAAYAAgAAQAAAAEAAAAZAAgAAQACAAAAAAAaAAgAAQAAAAAAAAAbAAgAAQAAAAEAAAAcAAgAAQACAAAAAAAeAAcAAQAAAAAAAAAeAAgAAQAAAAEAAAAeAAkAAQADAAAAAAAeAAoAAQAAAAAAAAAeAAsAAQAAAAEAAAAeAAwAAQADAAAAAAAeAA0AAQAAAAAAAAAeAA4AAQAAAAEAAAAdAA4AAQAEAAAAAAAdAAgAAQAAAAAAAAAVAA4AAQAAAAAAAAAYAA4AAQAAAAAAAAAaAA4AAQAAAAEAAAAbAA4AAQAAAAAAAAALABAAAQAAAAAAAAAOABAAAQAAAAAAAAAJAAsAAQAAAAEAAAAJAAwAAQABAAAAAAAJAA0AAQAAAAEAAAAJAA4AAQAAAAAAAAAJAAoAAQABAAAAAAAGAAMAAQAAAAEAAAAHAAMAAQACAAAAAAAIAAMAAQAAAAAAAAAJAAMAAQAAAAEAAAAKAAMAAQACAAAAAAALAAMAAQAAAAAAAAAMAAMAAQAAAAEAAAANAAMAAQACAAAAAAAOAAMAAQAAAAAAAAAPAAMAAQAAAAEAAAAQAAMAAQACAAAAAAARAAMAAQAAAAAAAAASAAMAAQAAAAEAAAATAAMAAQACAAAAAAAUAAMAAQAAAAAAAAAVAAMAAQAAAAEAAAAWAAMAAQACAAAAAAAXAAMAAQAAAAAAAAAYAAMAAQAAAAEAAAAZAAMAAQACAAAAAAAaAAMAAQAAAAAAAAAbAAMAAQAAAAEAAAAcAAMAAQACAAAAAAAdAAMAAQAAAAAAAAAeAAMAAQAAAAEAAAAGAAQAAQABAAAAAAAGAAUAAQAAAAEAAAAeAAQAAQADAAAAAAAeAAUAAQAAAAEAAAAeAAYAAQADAAAAAAAPAAQAAQADAAAAAAAPAAUAAQAAAAEAAAAQAAUAAQACAAAAAAARAAUAAQAAAAAAAAASAAUAAQAAAAAAAAATAAUAAQAAAAAAAAAUAAUAAQAAAAAAAAAVAAUAAQAAAAAAAAAWAAUAAQAAAAAAAAAXAAUAAQAAAAAAAAAYAAUAAQAAAAEAAAAYAAYAAQADAAAAAAAYAAcAAQAAAAAAAAAaAAsAAQAAAAEAAAAaAAwAAQAAAAAAAAAaAA0AAQABAAAAAAARAAsAAQAAAAEAAAASAAsAAQAAAAAAAAATAAsAAQAAAAAAAAAUAAsAAQAEAAAAAAAVAAsAAQAAAAEAAAAWAAsAAQAAAAAAAAAXAAsAAQAAAAAAAAAYAAsAAQAAAAAAAAAZAAsAAQAEAAAAAAARAAwAAQADAAAAAAARAA0AAQAAAAAAAAAVAAkAAQABAAAAAAAVAAoAAQAAAAAAAAAPAAkAAQADAAAAAAAPAAoAAQAAAAAAAAAPAAsAAQAAAAEAAAANAAsAAQAAAAEAAAAOAAsAAQAEAAAAAAANAAwAAQADAAAAAAANAA0AAQAAAAAAAAANAA4AAQAAAAAAAAANAA8AAQAAAAAAAAA=") tile_set = ExtResource("1_3jghe") [node name="TestDataLayer" type="TileMapLayer" parent="."] +visible = false scale = Vector2(2, 2) tile_map_data = PackedByteArray("AAAKABAAAQAEAAAAAAALABAAAQAAAAAAAAAMABAAAQAAAAAAAAANABAAAQAAAAAAAAAOABAAAQAAAAAAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAARABAAAQAAAAEAAAAJABAAAQAAAAEAAAANAA4AAQABAAAAAAANAA8AAQAAAAAAAAANAA0AAQAAAAEAAAAOAA0AAQACAAAAAAAPAA0AAQAAAAAAAAAQAA0AAQAAAAEAAAA=") tile_set = ExtResource("1_3jghe") [node name="NavigationGraph" type="Node2D" parent="."] script = ExtResource("3_ww84c") + +[node name="Player" type="CharacterBody2D" parent="."] +position = Vector2(-75, 73) +scale = Vector2(0.640001, 0.640001) +collision_mask = 3 +script = ExtResource("4_djnau") +metadata/_edit_group_ = true + +[node name="Icon" type="Sprite2D" parent="Player"] +scale = Vector2(0.4, 0.4) +texture = ExtResource("5_3opuj") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +shape = SubResource("CapsuleShape2D_cgpao") + +[node name="ResultLabel" type="Label" parent="."] +offset_left = 442.0 +offset_top = 574.0 +offset_right = 701.0 +offset_bottom = 646.0 +theme_override_constants/outline_size = 15 +theme_override_font_sizes/font_size = 51 +text = "Rolled a 2" diff --git a/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd b/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd index 097a5e9..f9cc16d 100644 --- a/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd +++ b/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd @@ -2,20 +2,90 @@ extends Node2D @onready var ground_layer: TileMapLayer = $GroundLayer @onready var path_layer: TileMapLayer = $PathLayer -@onready var data_layer: TileMapLayer = $TestDataLayer +@onready var data_layer: TileMapLayer = $DataLayer @onready var navigation_graph: MPNavigationGraph = $NavigationGraph -const DIRECTIONS: Dictionary = { - "up": Vector2(0, -1), - "down": Vector2(0, 1), - "left": Vector2(-1, 0), - "right": Vector2(1, 0) - } -var node_positions: Dictionary = {} +# +@onready var player: CharacterBody2D = $Player + +var last_dice_result: int = 0 +# +var global_transform_size: Vector2 = Vector2(0, 0) +# +const DIRECTIONS: Dictionary = { + "up": Vector2(0, -1), + "down": Vector2(0, 1), + "left": Vector2(-1, 0), + "right": Vector2(1, 0) + } +var node_positions: Dictionary = {} func _ready() -> void: + global_transform_size = Vector2(16, 16) * data_layer.transform.get_scale() + build_graph() + # place the player at the first node + var current_player_position: Vector2 = node_positions.keys()[0] + player.global_position = local_to_world(current_player_position) + + # bring player to top + player.z_index = 1 + + roll_dice() + + player.finished_movement.connect(roll_dice) + + +func _physics_process(delta: float) -> void: + if Input.is_action_just_pressed("draw_toggle_nodes") or Input.is_action_just_pressed("draw_toggle_edges"): + navigation_graph.draw_nodes = !navigation_graph.draw_nodes + navigation_graph.draw_edges = !navigation_graph.draw_edges + navigation_graph.queue_redraw() + +var dice_controls_min: int = 2 +var dice_controls_max: int = 8 + + +func roll_dice() -> void: + last_dice_result = randi() % (dice_controls_max - dice_controls_min + 1) + dice_controls_min + print("Dice result: ", last_dice_result) + $ResultLabel.text = "Rolled a " + str(last_dice_result) + + # Find possible movement options + var movement_options: Array[MPNavigationNode] = find_nodes_with_distance(world_to_local(player.global_position), last_dice_result) + # visualize by spawning an indicator at each possible node, with a click event to move the player + for node in movement_options: + # res://scenes/mario-party/TileIndicator.tscn + var indicator_scene: Node2D = preload("res://scenes/mario-party/TileIndicator.tscn").instantiate() + indicator_scene.scale = Vector2(2, 2) + var area_node: Area2D = indicator_scene.get_node("area") + area_node.set_data(node.position, "player_movement") + area_node.indicator_clicked.connect(_on_indicator_clicked) + indicator_scene.global_position = local_to_world(node.get_position()) + add_child(indicator_scene) + + +func _on_indicator_clicked(pos: Vector2, type: String) -> void: + print("Indicator clicked: ", type, " ", pos) + if type == "player_movement": + player.move_to(pos) + # delete all indicators + for child in get_children(): + if child is Node2D: + var area_node: Area2D = child.get_node("area") + if area_node != null: + if area_node.get_type() == "player_movement": + child.queue_free() + + +func local_to_world(location: Vector2) -> Vector2: + return location * global_transform_size + global_transform_size / 2 + + +func world_to_local(location: Vector2) -> Vector2: + return (location - global_transform_size / 2) / global_transform_size + func build_graph() -> void: print("Identifying nodes") @@ -24,9 +94,13 @@ func build_graph() -> void: var tile_data: TileData = data_layer.get_cell_tile_data(position) var is_tile: bool = tile_data.get_custom_data("is_tile") if is_tile: - var node: NavigationNode = navigation_graph.add_node(position.x, position.y) + var node: MPNavigationNode = navigation_graph.add_node(position.x, position.y) node_positions[position] = node - print(Vector2(position)) + var indicator_scene: Node2D = preload("res://scenes/mario-party/TileIndicator.tscn").instantiate() + var area_node: Area2D = indicator_scene.get_node("area") + area_node.set_display_type("node") + indicator_scene.global_position = local_to_world(position) + add_child(indicator_scene) # Step 2: Connect nodes using flood-fill based on walkable tiles print("Connecting nodes") @@ -38,19 +112,19 @@ func connect_node(start_position: Vector2) -> void: var start_node = node_positions.get(Vector2i(start_position)) var visited: Dictionary = {} visited[start_position] = true - print("Connecting node at ", start_position) + # print("Connecting node at ", start_position) # For each direction, perform flood-fill for dir_name in DIRECTIONS.keys(): var direction = DIRECTIONS[dir_name] var next_position = start_position + direction - print("Checking direction ", dir_name, " from ", start_position, " to ", next_position) + # print("Checking direction ", dir_name, " from ", start_position, " to ", next_position) # Ensure the first tile respects the direction if not is_valid_direction(next_position, dir_name): continue - print("Flood-fill in direction ", dir_name, " from ", next_position) + # print("Flood-fill in direction ", dir_name, " from ", next_position) # Perform flood-fill from the valid tile var connected_nodes: Array = flood_fill(next_position, visited) @@ -70,7 +144,7 @@ func flood_fill(start_position: Vector2, visited: Dictionary) -> Array: while stack.size() > 0: var current_position = stack.pop_back() - print(" - Visiting ", current_position) + # print(" - Visiting ", current_position) # Skip if already visited if visited.has(current_position): @@ -90,10 +164,8 @@ func flood_fill(start_position: Vector2, visited: Dictionary) -> Array: # If this position is a node, add it to the result if is_tile: - print(" - Found node tile at ", current_position) + # print(" - Found node tile at ", current_position) connected_nodes.append(current_position) - else: - print(" - Found walkable tile at ", current_position) # Add neighboring tiles to the stack if they respect the direction for dir_name in DIRECTIONS.keys(): @@ -110,16 +182,54 @@ func flood_fill(start_position: Vector2, visited: Dictionary) -> Array: func is_valid_direction(position: Vector2, required_dir: String) -> bool: var tile_data: TileData = data_layer.get_cell_tile_data(position) if tile_data == null: - print(" L Cancelled due to null tile data") return false var is_walkable: bool = tile_data.get_custom_data("is_walkable") var walk_dir: String = tile_data.get_custom_data("walk_dir") - # If walk_dir is empty, treat it as "any" direction if walk_dir == "": walk_dir = "any" - print(" L ", position, " ", is_walkable, " ", walk_dir, " ", required_dir) + # print(" L ", position, " ", is_walkable, " ", walk_dir, " ", required_dir) # Check if the tile is walkable and allows movement in the required direction return is_walkable and (walk_dir == required_dir or walk_dir == "any") + + +# the first function that evaluates the finished graph +# it is given a starting position and a distance in integers, which represent the amount of nodes to travel to reach the target node(s) +# it will find any nodes that are the given distance away from the starting node and return them in an array +# distance here is the amount of nodes to travel, not the actual distance in pixels +# must use the MPNavigationNode class and the navigation_graph.get_connections(node: MPNavigationNode) function +func find_nodes_with_distance(start_position: Vector2, distance: int) -> Array[MPNavigationNode]: + var start_node = node_positions.get(Vector2i(start_position)) + if start_node == null: + print("Error: No node found at starting position ", start_position) + return [] + + # Initialize BFS + var queue: Array = [[start_node, 0]] # Each element is [node, current_distance] + var visited: Dictionary = {start_node: true} + var result_nodes: Array[MPNavigationNode] = [] + + while queue.size() > 0: + var current = queue.pop_front() + var current_node: MPNavigationNode = current[0] + var current_distance: int = current[1] + + # If the target distance is reached, add the node to the result + if current_distance == distance: + result_nodes.append(current_node) + continue # Do not explore further from this node + + # If the current distance exceeds the target, stop exploring + if current_distance > distance: + break + + # Explore neighbors of the current node + var neighbors: Array[MPNavigationNode] = navigation_graph.get_connections(current_node) + for neighbor in neighbors: + if not visited.has(neighbor): + visited[neighbor] = true + queue.append([neighbor, current_distance + 1]) + + return result_nodes diff --git a/pathfinding-algorithms/scenes/mario-party/PlayerController.gd b/pathfinding-algorithms/scenes/mario-party/PlayerController.gd new file mode 100644 index 0000000..70bad1f --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/PlayerController.gd @@ -0,0 +1,59 @@ +extends CharacterBody2D + +signal finished_movement() + +const MAX_SPEED: float = 300.0 +const ACCELERATION: int = 4800 +const SNAP_DISTANCE: float = 2.0 +var frozen: bool = false +var target: Vector2 = Vector2(-1, -1) +var path: Array[MPNavigationNode] = [] +var current_path_index: int = 0 + +@onready var navigation_graph = $"../NavigationGraph" + + +func move_to(target: Vector2) -> void: + var using_position: Vector2 = (global_position - Vector2(16, 16)) / 32 + var pathfinding_result: MPPathfindingResult = navigation_graph.determine_next_position(using_position, target) + navigation_graph.draw_pathfinding_result(pathfinding_result) + path = pathfinding_result.path + current_path_index = 0 + print("Moving to ", target) + for node in path: + print(" - ", node.position) + + +func _physics_process(delta: float) -> void: + if Input.is_action_just_pressed("ui_select"): + frozen = !frozen + + if frozen or path.size() == 0: + return + + var movement: Vector2 = Vector2() + + if current_path_index < path.size(): + var next_position: Vector2 = path[current_path_index].global_position * 32 + Vector2(16, 16) + + var distance_to_next: float = global_position.distance_to(next_position) + if distance_to_next > SNAP_DISTANCE: + movement = (next_position - global_position).normalized() * ACCELERATION + else: + # snap to the next node if close enough + global_position = next_position + current_path_index += 1 + + # if the end of the path is reached, stop movement + if current_path_index >= path.size(): + path.clear() + target = Vector2(-1, -1) + finished_movement.emit() + navigation_graph.clear_pathfinding_result() + + # Immediate deceleration for tight control + velocity = movement + if velocity.length() > MAX_SPEED: + velocity = velocity.normalized() * MAX_SPEED + + move_and_slide() diff --git a/pathfinding-algorithms/scenes/mario-party/TileIndicator.tscn b/pathfinding-algorithms/scenes/mario-party/TileIndicator.tscn new file mode 100644 index 0000000..128cea7 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/TileIndicator.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=4 format=3 uid="uid://b4btlpsdkstnw"] + +[ext_resource type="Texture2D" uid="uid://dpg3am0sik4s3" path="res://scenes/mario-party/img/tile_highlight.png" id="1_c8wfh"] +[ext_resource type="Script" path="res://scenes/mario-party/tile_indicator.gd" id="1_eusgv"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ywle7"] +size = Vector2(16, 16) + +[node name="TileIndicator" type="Node2D"] + +[node name="area" type="Area2D" parent="."] +script = ExtResource("1_eusgv") + +[node name="Sprite2D" type="Sprite2D" parent="area"] +texture_filter = 1 +texture = ExtResource("1_c8wfh") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="area"] +shape = SubResource("RectangleShape2D_ywle7") diff --git a/pathfinding-algorithms/scenes/mario-party/img/tile_highlight.png b/pathfinding-algorithms/scenes/mario-party/img/tile_highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..b8767aa898ca69aa03dc677b6e3800935f758760 GIT binary patch literal 642 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL9r6oh?3y^w370~qEv=}#LT=BJwMkF1yeo4 z@6F#Q166EEjqptK^weVD0CHFvq!?Kl7=bJ=AeM%*L2l7tWCn{f0ojI(ObmQLItqw0 z+gZTk89+7&Bmgl;Ka57Pl7X3lVFEh?3sBy`$k>2!0mMv@de#LHb0z`VAixAPg$b-O z$kGDHg6c9fFaXIWFHt)ZFtPUc8jbh71;TGw|2 z5!WLrehF&-mR9pkzngOKf{U=AP3MBu?_aNzJC#^+oW1|ms&!SDL#~F1efXMXZ6y9^ zpM{dx29fln;M`lmT^ws0y82Vr9oZ`KLstILOqaaENe$xn3(F>K5tu(YeVcCIQH{DL zkEiGBL{2|#u2^w;`Ha&d`=7WzIqJ>jyw@&;XtwRokQ%(h#2!0mMv@de#LHb0z`VAixAPg$b-O z$kGDHg6c9fFaXIWFHt)ZQ_JaTy1re0q)u=!YB# zZD#j2-16XP6VH!*XZaqn)jxPLeGkLobIEBpeD5@r-qkH#xn$}TA?XWVy&?0qpFHdC zlE2_duO55mL+1B8y<2^<&bW%$)`*_lto0`v0IR6)K@>Gjek$xkPwCA+WP0QzUj*HEoHpeT0 Pe97SH>gTe~DWM4fJshEL literal 0 HcmV?d00001 diff --git a/pathfinding-algorithms/scenes/mario-party/img/tile_node.png.import b/pathfinding-algorithms/scenes/mario-party/img/tile_node.png.import new file mode 100644 index 0000000..0b161da --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/img/tile_node.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bn6ccsbh6nga0" +path="res://.godot/imported/tile_node.png-d5169d56110746a53897400abc7e745e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/mario-party/img/tile_node.png" +dest_files=["res://.godot/imported/tile_node.png-d5169d56110746a53897400abc7e745e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/pathfinding-algorithms/scenes/mario-party/tile_indicator.gd b/pathfinding-algorithms/scenes/mario-party/tile_indicator.gd new file mode 100644 index 0000000..72e1512 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/tile_indicator.gd @@ -0,0 +1,26 @@ +extends Area2D + +signal indicator_clicked() +var pos: Vector2 = Vector2() +var type: String = "" + + +func _input_event(viewport: Viewport, event: InputEvent, shape_idx: int) -> void: + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + indicator_clicked.emit(pos, type) + + +func set_data(p: Vector2, t: String) -> void: + pos = p + type = t + +func get_type() -> String: + return type + +func set_display_type(t: String) -> void: + if t == "node": + $Sprite2D.texture = preload("res://scenes/mario-party/img/tile_node.png") as Texture + elif t == "player_movement": + $Sprite2D.texture = preload("res://scenes/mario-party/img/tile_highlight.png") as Texture + else: + push_error("Invalid type: %s" % t)