From 5ab6f82f4b73e44d1617dda7c5f730a0676b3118 Mon Sep 17 00:00:00 2001 From: Yan Wittmann Date: Tue, 19 Nov 2024 11:51:36 +0100 Subject: [PATCH] Mario Party --- pathfinding-algorithms/project.godot | 2 +- .../scenes/mario-party/MPNavigationGraph.gd | 204 ++++++++++++++++++ .../scenes/mario-party/MPNavigationNode.gd | 2 + .../scenes/mario-party/MarioParty.tscn | 34 +++ .../mario-party/MarioPartyManagement.gd | 125 +++++++++++ .../scenes/mario-party/MarioPartyTiles.tres | 122 +++++++++++ .../scenes/mario-party/img/data_layer.png | Bin 0 -> 1045 bytes .../mario-party/img/data_layer.png.import | 34 +++ 8 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd create mode 100644 pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd create mode 100644 pathfinding-algorithms/scenes/mario-party/MarioParty.tscn create mode 100644 pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd create mode 100644 pathfinding-algorithms/scenes/mario-party/MarioPartyTiles.tres create mode 100644 pathfinding-algorithms/scenes/mario-party/img/data_layer.png create mode 100644 pathfinding-algorithms/scenes/mario-party/img/data_layer.png.import diff --git a/pathfinding-algorithms/project.godot b/pathfinding-algorithms/project.godot index d992e90..5ce20ed 100644 --- a/pathfinding-algorithms/project.godot +++ b/pathfinding-algorithms/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="pathfinding-algorithms" -run/main_scene="res://scenes/custom-solver/custom-graph-solver.tscn" +run/main_scene="res://scenes/mario-party/MarioParty.tscn" config/features=PackedStringArray("4.3", "Forward Plus") config/icon="res://icon.svg" diff --git a/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd b/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd new file mode 100644 index 0000000..8b79907 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/MPNavigationGraph.gd @@ -0,0 +1,204 @@ +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 + + +func all_nodes() -> Array[NavigationNode]: + # 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 + # on the dictionary, so i had to do this workaround. + var keys: Array = navigation_nodes.keys() + var nodes: Array[NavigationNode] = [] + for key in keys: + if key is NavigationNode: + nodes.append(key) + else: + push_error("Key is not a NavigationNode: %s" % key) + return nodes + + +func get_connections(from: NavigationNode) -> Array[NavigationNode]: + # the same problem as the all_nodes() function + var connections: Array = navigation_nodes[from] + var nodes: Array[NavigationNode] = [] + for connection in connections: + if connection is NavigationNode: + nodes.append(connection) + else: + push_error("Connection is not a NavigationNode: %s" % connection) + return nodes + + +func add_connection(from: NavigationNode, to: NavigationNode) -> 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: + if merge_threshold > 0: + var closest_node: NavigationNode = 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() + 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 + for node in all_nodes(): + var distance: float = position.distance_to(node.position) + if distance < closest_distance: + closest_node = node + closest_distance = distance + return closest_node + + +func remove_connection(from: NavigationNode, to: NavigationNode) -> void: + if all_nodes().has(from): + navigation_nodes[from].erase(to) + + +func remove_node(node: NavigationNode) -> void: + navigation_nodes.erase(node) + for other_node in all_nodes(): + if other_node != node: + remove_connection(other_node, node) + + +func _draw() -> void: + print("Drawing navigation graph") + if draw_nodes or draw_edges: + for from in all_nodes(): + if draw_edges: + for to in get_connections(from): + draw_line(local_to_world(from.position), local_to_world(to.position), Color.RED, 1, false) + if draw_nodes: + draw_circle(local_to_world(from.position), 5, Color.RED) + + if latest_navigation_result != null: + 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) + + +func local_to_world(location: Vector2) -> Vector2: + return location * 32 + Vector2(16, 16) + +func draw_pathfinding_result(result: PathfindingResult) -> 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() + + # Find the closest node to the current position + var start_node: NavigationNode = find_closest_node_with_threshold(current_position, INF) + if start_node == null: + # No nodes exist; cannot navigate + result.is_next_target = true + result.next_position = current_position + return result + + # Find the closest node to the target position + var end_node: NavigationNode = find_closest_node_with_threshold(target_position, INF) + if end_node == null: + # No nodes exist; cannot navigate + result.is_next_target = true + result.next_position = current_position + return result + + # If the start and end nodes are the same, go directly to the target position + if start_node == end_node: + result.is_next_target = true + result.next_position = target_position + return result + + # Run Dijkstra's algorithm to find the path + var path: Array[NavigationNode] = dijkstra(start_node, end_node) + result.path = path + + # If a path is found, return the position of the next node in the path + if path.size() > 1: + # Next node in the path + result.next_position = path[1].position + return result + elif path.size() == 1: + # Directly reachable + result.is_next_target = true + result.next_position = target_position + else: + # No path found; return current position + result.is_next_target = true + result.next_position = current_position + + return result + + +func array_contains_node(arr: Array, node: NavigationNode) -> 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 = {} + + 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] + for node in open_set: + if distances[node] < current_distance: + current_node = node + current_distance = distances[node] + + # If the end node is reached, reconstruct the path + if current_node == end_node: + var path: Array[NavigationNode] = [] + var node: NavigationNode = end_node + while node != null: + path.insert(0, node) + node = previous_nodes.get(node, null) + return path + + open_set.erase(current_node) + closed_set.append(current_node) + + # Examine neighbors of the current node + var neighbors = get_connections(current_node) + for neighbor in neighbors: + if array_contains_node(closed_set, neighbor): + continue + + var tentative_distance: float = distances[current_node] + current_node.position.distance_to(neighbor.position) + + if not array_contains_node(open_set, neighbor) or tentative_distance < distances.get(neighbor, INF): + distances[neighbor] = tentative_distance + previous_nodes[neighbor] = current_node + if not array_contains_node(open_set, neighbor): + open_set.append(neighbor) + + # No path found; return an empty array + return [] diff --git a/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd b/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd new file mode 100644 index 0000000..2a2d7cb --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/MPNavigationNode.gd @@ -0,0 +1,2 @@ +class_name MPNavigationNode +extends Node2D diff --git a/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn b/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn new file mode 100644 index 0000000..a064646 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/MarioParty.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=4 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"] + +[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="."] +visible = false +scale = Vector2(2, 2) +tile_map_data = PackedByteArray("AAAGAAYAAQAAAAAAAAAGAAcAAQABAAAAAAAGAAgAAQAAAAEAAAAGAAkAAQABAAAAAAAGAAoAAQAAAAEAAAAGAAsAAQAAAAAAAAAGAAwAAQAAAAAAAAAGAA0AAQABAAAAAAAGAA4AAQAAAAEAAAAGAA8AAQABAAAAAAAGABAAAQAAAAEAAAARAA4AAQAAAAEAAAASAA4AAQAAAAAAAAATAA4AAQAEAAAAAAAUAA4AAQAAAAEAAAAWAA4AAQAEAAAAAAAXAA4AAQAAAAEAAAAZAA4AAQAEAAAAAAAcAA4AAQAAAAAAAAARAA8AAQADAAAAAAARABAAAQAAAAEAAAAHABAAAQAAAAAAAAAIABAAAQAEAAAAAAAJABAAAQAAAAEAAAAKABAAAQAAAAAAAAAMABAAAQAEAAAAAAANABAAAQAAAAEAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAAJAAgAAQAAAAEAAAAJAAkAAQAAAAAAAAAJAA8AAQABAAAAAAAHAAgAAQACAAAAAAAIAAgAAQAAAAAAAAAKAAgAAQACAAAAAAALAAgAAQAAAAAAAAAMAAgAAQAAAAEAAAANAAgAAQACAAAAAAAOAAgAAQAAAAAAAAAPAAgAAQAAAAEAAAAQAAgAAQACAAAAAAARAAgAAQAAAAAAAAASAAgAAQAAAAEAAAATAAgAAQACAAAAAAAUAAgAAQAAAAAAAAAVAAgAAQAAAAEAAAAWAAgAAQACAAAAAAAXAAgAAQAAAAAAAAAYAAgAAQAAAAEAAAAZAAgAAQACAAAAAAAaAAgAAQAAAAAAAAAbAAgAAQAAAAEAAAAcAAgAAQACAAAAAAAeAAcAAQAAAAAAAAAeAAgAAQAAAAEAAAAeAAkAAQADAAAAAAAeAAoAAQAAAAAAAAAeAAsAAQAAAAEAAAAeAAwAAQADAAAAAAAeAA0AAQAAAAAAAAAeAA4AAQAAAAEAAAAdAA4AAQAEAAAAAAAdAAgAAQAAAAAAAAAVAA4AAQAAAAAAAAAYAA4AAQAAAAAAAAAaAA4AAQAAAAEAAAAbAA4AAQAAAAAAAAALABAAAQAAAAAAAAAOABAAAQAAAAAAAAAJAAsAAQAAAAEAAAAJAAwAAQABAAAAAAAJAA0AAQAAAAEAAAAJAA4AAQAAAAAAAAAJAAoAAQABAAAAAAAGAAMAAQAAAAEAAAAHAAMAAQACAAAAAAAIAAMAAQAAAAAAAAAJAAMAAQAAAAEAAAAKAAMAAQACAAAAAAALAAMAAQAAAAAAAAAMAAMAAQAAAAEAAAANAAMAAQACAAAAAAAOAAMAAQAAAAAAAAAPAAMAAQAAAAEAAAAQAAMAAQACAAAAAAARAAMAAQAAAAAAAAASAAMAAQAAAAEAAAATAAMAAQACAAAAAAAUAAMAAQAAAAAAAAAVAAMAAQAAAAEAAAAWAAMAAQACAAAAAAAXAAMAAQAAAAAAAAAYAAMAAQAAAAEAAAAZAAMAAQACAAAAAAAaAAMAAQAAAAAAAAAbAAMAAQAAAAEAAAAcAAMAAQACAAAAAAAdAAMAAQAAAAAAAAAeAAMAAQAAAAEAAAAGAAQAAQABAAAAAAAGAAUAAQAAAAEAAAAeAAQAAQADAAAAAAAeAAUAAQAAAAEAAAAeAAYAAQADAAAAAAAPAAQAAQADAAAAAAAPAAUAAQAAAAEAAAAQAAUAAQACAAAAAAARAAUAAQAAAAAAAAASAAUAAQAAAAAAAAATAAUAAQAAAAAAAAAUAAUAAQAAAAAAAAAVAAUAAQAAAAAAAAAWAAUAAQAAAAAAAAAXAAUAAQAAAAAAAAAYAAUAAQAAAAEAAAAYAAYAAQADAAAAAAAYAAcAAQAAAAAAAAA=") +tile_set = ExtResource("1_3jghe") + +[node name="TestDataLayer" type="TileMapLayer" parent="."] +scale = Vector2(2, 2) +tile_map_data = PackedByteArray("AAAKABAAAQAEAAAAAAALABAAAQAAAAAAAAAMABAAAQAAAAAAAAANABAAAQAAAAAAAAAOABAAAQAAAAAAAAAPABAAAQAAAAAAAAAQABAAAQAEAAAAAAARABAAAQAAAAEAAAAJABAAAQAAAAEAAAANAA4AAQABAAAAAAANAA8AAQAAAAAAAAANAA0AAQAAAAEAAAAOAA0AAQACAAAAAAAPAA0AAQAAAAAAAAAQAA0AAQAAAAEAAAA=") +tile_set = ExtResource("1_3jghe") + +[node name="NavigationGraph" type="Node2D" parent="."] +script = ExtResource("3_ww84c") diff --git a/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd b/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd new file mode 100644 index 0000000..097a5e9 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/MarioPartyManagement.gd @@ -0,0 +1,125 @@ +extends Node2D + +@onready var ground_layer: TileMapLayer = $GroundLayer +@onready var path_layer: TileMapLayer = $PathLayer +@onready var data_layer: TileMapLayer = $TestDataLayer +@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 = {} + + +func _ready() -> void: + build_graph() + + +func build_graph() -> void: + print("Identifying nodes") + # Step 1: Place nodes at positions where is_tile is true + for position in data_layer.get_used_cells(): + 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) + node_positions[position] = node + print(Vector2(position)) + + # Step 2: Connect nodes using flood-fill based on walkable tiles + print("Connecting nodes") + for position in node_positions.keys(): + connect_node(position) + + +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) + + # 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) + + # 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) + + # Perform flood-fill from the valid tile + var connected_nodes: Array = flood_fill(next_position, visited) + + # Add connections between the start node and found nodes + for target_position in connected_nodes: + if target_position != start_position: + if node_positions.has(Vector2i(target_position)): + var target_node = node_positions.get(Vector2i(target_position)) + navigation_graph.add_connection(start_node, target_node) + print(start_position, " --> ", target_position) + + +func flood_fill(start_position: Vector2, visited: Dictionary) -> Array: + var stack: Array[Vector2] = [start_position] + var connected_nodes: Array[Vector2] = [] + + while stack.size() > 0: + var current_position = stack.pop_back() + print(" - Visiting ", current_position) + + # Skip if already visited + if visited.has(current_position): + continue + + visited[current_position] = true + + # Skip if not walkable + var tile_data: TileData = data_layer.get_cell_tile_data(current_position) + if tile_data == null: + continue + + var is_walkable: bool = tile_data.get_custom_data("is_walkable") + var is_tile: bool = tile_data.get_custom_data("is_tile") + if (not is_walkable) and (not is_tile): + continue + + # If this position is a node, add it to the result + if is_tile: + 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(): + var direction = DIRECTIONS[dir_name] + var neighbor_position = current_position + direction + + if not visited.has(neighbor_position): + if is_valid_direction(current_position, dir_name): + stack.append(neighbor_position) + + return connected_nodes + + +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) + + # 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") diff --git a/pathfinding-algorithms/scenes/mario-party/MarioPartyTiles.tres b/pathfinding-algorithms/scenes/mario-party/MarioPartyTiles.tres new file mode 100644 index 0000000..a12a922 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/MarioPartyTiles.tres @@ -0,0 +1,122 @@ +[gd_resource type="TileSet" load_steps=7 format=3 uid="uid://cm6wi7fjgfk56"] + +[ext_resource type="Texture2D" uid="uid://cmb6k735nhxmy" path="res://scenes/mario-party/img/data_layer.png" id="1_pdyr2"] +[ext_resource type="Texture2D" uid="uid://bngfh7nslvij1" path="res://addons/sprout_lands_tilemap/assets/Tilesets/Grass.png" id="2_ev1xx"] +[ext_resource type="Texture2D" uid="uid://cvemyer4jq6we" path="res://addons/sprout_lands_tilemap/assets/Objects/Paths.png" id="3_eigvu"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_tp5r2"] +texture = ExtResource("1_pdyr2") +0:0/0 = 0 +0:0/0/custom_data_0 = true +0:1/0 = 0 +0:1/0/custom_data_1 = true +1:0/0 = 0 +1:0/0/custom_data_0 = true +1:0/0/custom_data_2 = "up" +2:0/0 = 0 +2:0/0/custom_data_0 = true +2:0/0/custom_data_2 = "right" +3:0/0 = 0 +3:0/0/custom_data_0 = true +3:0/0/custom_data_2 = "down" +4:0/0 = 0 +4:0/0/custom_data_0 = true +4:0/0/custom_data_2 = "left" + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_m45pk"] +texture = ExtResource("2_ev1xx") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +6:1/0 = 0 +0:2/0 = 0 +1:2/0 = 0 +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +5:2/0 = 0 +6:2/0 = 0 +7:2/0 = 0 +8:2/0 = 0 +9:2/0 = 0 +0:3/0 = 0 +1:3/0 = 0 +2:3/0 = 0 +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +6:3/0 = 0 +7:3/0 = 0 +8:3/0 = 0 +9:3/0 = 0 +0:4/0 = 0 +1:4/0 = 0 +2:4/0 = 0 +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +6:4/0 = 0 +7:4/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +0:5/0 = 0 +1:5/0 = 0 +2:5/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +5:5/0 = 0 +6:5/0 = 0 +7:5/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +0:6/0 = 0 +1:6/0 = 0 +2:6/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +5:6/0 = 0 +6:6/0 = 0 +7:6/0 = 0 +0:7/0 = 0 +1:7/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +6:7/0 = 0 +7:7/0 = 0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_xi3gi"] +texture = ExtResource("3_eigvu") +0:0/0 = 0 +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +0:2/0 = 0 +1:2/0 = 0 +2:2/0 = 0 +1:3/0 = 0 +2:3/0 = 0 +3:3/0 = 0 + +[resource] +custom_data_layer_0/name = "is_walkable" +custom_data_layer_0/type = 1 +custom_data_layer_1/name = "is_tile" +custom_data_layer_1/type = 1 +custom_data_layer_2/name = "walk_dir" +custom_data_layer_2/type = 4 +sources/1 = SubResource("TileSetAtlasSource_tp5r2") +sources/2 = SubResource("TileSetAtlasSource_m45pk") +sources/3 = SubResource("TileSetAtlasSource_xi3gi") diff --git a/pathfinding-algorithms/scenes/mario-party/img/data_layer.png b/pathfinding-algorithms/scenes/mario-party/img/data_layer.png new file mode 100644 index 0000000000000000000000000000000000000000..22e306b409ceaf523e4572d95f2cf963223e2954 GIT binary patch literal 1045 zcmeAS@N?(olHy`uVBq!ia0vp^3xK$RgBeKf-aAPXNHG=%xjQkeJ16rJ$YDu$^mSxl z*x1kgCy^D%uL$r7asB`Q|DKEg4_^82T=)OQ`~NZh|KlhAfA#VIwa5Q&KK(y?*MF_t z|2ld9=kED$Rq?-k;s4vu{@;7?ziP?d_W!<3|F!e}>*oKTxaGe_&i{b+|A8I-L15RjOeSEA?V8lqsT zXZXGO`(&VsEvXTnX`Y^13>-iXD}xjxD+42t>myuy_WL4FU;34AKvyQLJPD#=!)31{R>afswHR;{u48AoZ*ZAm&U0vO$0eXbKZp zWss!>kOkFcXkY-6Oa3?(G-+%j@ zqM}t|Z>~;X7*})N^=zTl!?}$Y>RQYAeYUUdREphmJ!^aPt~D2Gn=j_Bwz?Y^KmDA8 zz5G2^zNgFIN%!PLiK{Q(s5jSS_6x78%*!{2*p=Q-NVz<#GS6q@g@ZC0k%5mABX=M{`>KIG@e*8#h^Y621OxMNB_ok>j-=6gPcK)uSZOg0e*F8DdQ>AP# z^?i0Pi(lBkrr#@P$1%Cv{{M7yr*xKHw&bF9K4Hm?H!sD1FetwKSZsdx#(h=W%+2G! z-Y9u=$8J+t@b-!iHZ1?HsK~uya{@hn*GvXTmOIp6d~eUj9LVEhC~(w41j6|Gv+>u@jS?M63SEsFY>Q~k fSi#S~=l*`iV-7`8jGGGiLFvTP)z4*}Q$iB}PrSN| literal 0 HcmV?d00001 diff --git a/pathfinding-algorithms/scenes/mario-party/img/data_layer.png.import b/pathfinding-algorithms/scenes/mario-party/img/data_layer.png.import new file mode 100644 index 0000000..dc5d064 --- /dev/null +++ b/pathfinding-algorithms/scenes/mario-party/img/data_layer.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmb6k735nhxmy" +path="res://.godot/imported/data_layer.png-fa47112c212f2f74d495ba11ee8a8eff.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/mario-party/img/data_layer.png" +dest_files=["res://.godot/imported/data_layer.png-fa47112c212f2f74d495ba11ee8a8eff.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