feat: Add core map generation and management system
- Introduced MapData, MapGenerator, and MapPainter classes for procedural map generation. - Implemented LevelManager to handle level initialization and navigation. - Created TurnManager for managing turn order in a turn-based system. - Added Player and Enemy character classes with movement and turn-taking capabilities. - Established pathfinding using AStar2D in PathfindingHandler. - Integrated new scenes for player and enemy characters, along with world setup. - Included a new tileset for futuristic Zelda-themed assets.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
## LevelManager.gd
|
||||
# Manages the current level's data, visual representation, and navigation graph.
|
||||
# Responsible for generating, painting, and initializing the level, as well as providing pathfinding and coordinate helpers.
|
||||
extends Node
|
||||
|
||||
# The source of truth for the current level's layout (MapData resource).
|
||||
var _data: MapData
|
||||
# The TileMapLayer node where the map is visually rendered.
|
||||
var _layer: TileMapLayer
|
||||
|
||||
# Service objects for map generation, painting, and pathfinding.
|
||||
# MapGenerator and MapPainter are stateless; PathfindingHandler manages the navigation graph.
|
||||
var _generator: MapGenerator = MapGenerator.new()
|
||||
var _painter: MapPainter = MapPainter.new()
|
||||
var _pathfinding: PathfindingHandler = PathfindingHandler.new()
|
||||
|
||||
# Orchestrates the creation of a new level.
|
||||
# 1. Generates the map data.
|
||||
# 2. Paints the map visually.
|
||||
# 3. Builds the navigation graph for AI/pathfinding.
|
||||
# 4. Spawns the player at the correct location.
|
||||
func initialize(settings: MapSettings, layer: TileMapLayer, player: CharacterBody2D) -> void:
|
||||
_layer = layer
|
||||
|
||||
# 1. Generate the abstract map data (rooms, corridors, etc.).
|
||||
# This avoids side effects on the settings resource.
|
||||
_data = _generator.generate(settings)
|
||||
|
||||
# 2. Paint the visual layer for the player to see.
|
||||
# This does not modify the underlying map data.
|
||||
_painter.paint(_data, _layer)
|
||||
|
||||
# 3. Build the AStar graph for AI and navigation.
|
||||
# Reads directly from the grid stored in _data.
|
||||
_pathfinding.build(_data)
|
||||
|
||||
# 4. Finalize world state by spawning the player at the spawn point.
|
||||
# Uses the TileMapLayer to convert grid coordinates to world pixel positions.
|
||||
player.position = _layer.map_to_local(_data.spawn_point)
|
||||
|
||||
# Public API for other systems (like AI) to query the navigation grid.
|
||||
# Encapsulates the PathfindingHandler so callers don't need to know about it directly.
|
||||
func find_path(from: Vector2i, to: Vector2i) -> Array[Vector2i]:
|
||||
return _pathfinding.find_path(from, to)
|
||||
|
||||
# Coordinate conversion helpers — lets the player and other systems convert between world and tile coordinates without touching the TileMapLayer directly.
|
||||
func world_to_tile(world_pos: Vector2) -> Vector2i:
|
||||
return _layer.local_to_map(world_pos)
|
||||
|
||||
func tile_to_world(tile: Vector2i) -> Vector2:
|
||||
return _layer.map_to_local(tile)
|
||||
@@ -0,0 +1,61 @@
|
||||
## TurnManager.gd
|
||||
# Autoload singleton for managing turn order in a turn-based game.
|
||||
# Handles registration, sequencing, and signaling for all turn-taking entities.
|
||||
extends Node
|
||||
|
||||
# List of entities that participate in the turn order (e.g., Player, Enemies).
|
||||
var turn_entities: Array[Node] = []
|
||||
# Index of the entity whose turn is currently active.
|
||||
var current_index: int = 0
|
||||
# Whether the turn system is currently running.
|
||||
var active: bool = false
|
||||
|
||||
# Registers an entity to participate in the turn order.
|
||||
# Ensures no duplicates.
|
||||
func register_entity(entity: Node) -> void:
|
||||
if entity not in turn_entities:
|
||||
turn_entities.append(entity)
|
||||
|
||||
# Unregisters an entity (e.g., when it is removed or defeated).
|
||||
func unregister_entity(entity: Node) -> void:
|
||||
if entity in turn_entities:
|
||||
turn_entities.erase(entity)
|
||||
|
||||
# Starts the turn sequence for all registered entities.
|
||||
# Resets the index and begins the first turn.
|
||||
func start_turns() -> void:
|
||||
if turn_entities.size() == 0:
|
||||
return
|
||||
active = true
|
||||
current_index = 0
|
||||
_next_turn()
|
||||
|
||||
# Advances to the next entity's turn.
|
||||
# Connects to the entity's turn_finished signal and calls its take_turn() method.
|
||||
func _next_turn() -> void:
|
||||
if not active or turn_entities.size() == 0:
|
||||
return
|
||||
if current_index >= turn_entities.size():
|
||||
current_index = 0 # New round
|
||||
# Get the next entity in the list.
|
||||
var entity: Node = turn_entities[current_index]
|
||||
# Connect to the entity's turn_finished signal if not already connected.
|
||||
if not entity.is_connected("turn_finished", Callable(self, "_on_entity_turn_finished")):
|
||||
entity.connect("turn_finished", Callable(self, "_on_entity_turn_finished"))
|
||||
# Notify the entity to take its turn.
|
||||
entity.take_turn()
|
||||
|
||||
# Called when an entity finishes its turn (emits turn_finished).
|
||||
# Disconnects the signal and advances to the next entity.
|
||||
func _on_entity_turn_finished() -> void:
|
||||
# Disconnect to avoid duplicate connections.
|
||||
var entity: Node = turn_entities[current_index]
|
||||
if entity.is_connected("turn_finished", Callable(self, "_on_entity_turn_finished")):
|
||||
entity.disconnect("turn_finished", Callable(self, "_on_entity_turn_finished"))
|
||||
current_index += 1
|
||||
_next_turn()
|
||||
|
||||
# Optionally, stops the turn sequence and resets state.
|
||||
func stop_turns() -> void:
|
||||
active = false
|
||||
current_index = 0
|
||||
Reference in New Issue
Block a user