docs: add comments

This commit is contained in:
Kristofers Solo 2025-01-05 20:10:01 +02:00
parent cfaf565891
commit 3d158a4e7c
9 changed files with 147 additions and 15 deletions

View File

@ -10,6 +10,12 @@ use crate::{
use bevy::prelude::*;
/// Move floor entities to their target Y positions based on movement speed
///
/// # Behavior
/// - Calculates movement distance based on player speed and delta time
/// - Moves floors towards their target Y position
/// - Removes FloorYTarget component when floor reaches destination
pub fn move_floors(
mut commands: Commands,
mut maze_query: Query<(Entity, &mut Transform, &FloorYTarget), With<FloorYTarget>>,
@ -30,6 +36,13 @@ pub fn move_floors(
}
}
/// Handle floor transition events by setting up floor movement targets
///
/// # Behavior
/// - Checks if any floors are currently moving
/// - Processes floor transition events
/// - Sets target Y positions for all maze entities
/// - Updates current and next floor designations
pub fn handle_floor_transition_events(
mut commands: Commands,
mut maze_query: Query<(Entity, &Transform, &Floor, Option<&FloorYTarget>), With<HexMaze>>,

View File

@ -1,8 +1,14 @@
//! Maze asset management and generation.
//!
//! Module handles the creation and management of meshes and materials
//! used in the maze visualization, including hexagonal tiles and walls.
use super::resources::GlobalMazeConfig;
use crate::{
constants::WALL_OVERLAP_MODIFIER,
theme::{palette::rose_pine::RosePineDawn, prelude::ColorScheme},
};
use bevy::{prelude::*, utils::HashMap};
use std::f32::consts::FRAC_PI_2;
use strum::IntoEnumIterator;
@ -10,15 +16,26 @@ use strum::IntoEnumIterator;
const HEX_SIDES: u32 = 6;
const WHITE_EMISSION_INTENSITY: f32 = 10.;
/// Collection of mesh and material assets used in maze rendering.
///
/// This struct contains all the necessary assets for rendering maze components,
/// including hexagonal tiles, walls, and custom colored materials.
#[derive(Debug)]
pub struct MazeAssets {
/// Mesh for hexagonal floor tiles
pub hex_mesh: Handle<Mesh>,
/// Mesh for wall segments
pub wall_mesh: Handle<Mesh>,
/// Default material for hexagonal tiles
pub hex_material: Handle<StandardMaterial>,
/// Default material for walls
pub wall_material: Handle<StandardMaterial>,
/// Custom materials mapped to specific colors from the RosePineDawn palette
pub custom_materials: HashMap<RosePineDawn, Handle<StandardMaterial>>,
}
impl MazeAssets {
/// Creates a new instance of MazeAssets with all necessary meshes and materials.
pub fn new(
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<StandardMaterial>>,
@ -43,6 +60,7 @@ impl MazeAssets {
}
}
/// Generates a hexagonal mesh for floor tiles.
fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh {
let hexagon = RegularPolygon {
sides: HEX_SIDES,
@ -54,6 +72,7 @@ fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh {
Mesh::from(prism_shape).rotated_by(rotation)
}
/// Generates a square mesh for wall segments.
fn generate_square_mesh(depth: f32, wall_size: f32) -> Mesh {
let square = Rectangle::new(wall_size, wall_size);
let rectangular_prism = Extrusion::new(square, depth);
@ -62,6 +81,7 @@ fn generate_square_mesh(depth: f32, wall_size: f32) -> Mesh {
Mesh::from(rectangular_prism).rotated_by(rotation)
}
/// Creates a glowing white material for default tile appearance.
pub fn white_material() -> StandardMaterial {
StandardMaterial {
emissive: LinearRgba::new(

View File

@ -1,6 +1,11 @@
//! Maze components and configuration.
//!
//! Module defines the core components and configuration structures used
//! for maze generation and rendering, including hexagonal maze layouts,
//! tiles, walls, and maze configuration.
use super::GlobalMazeConfig;
use crate::floor::components::Floor;
use super::GlobalMazeConfig;
use bevy::prelude::*;
use hexlab::Maze;
use hexx::{Hex, HexLayout, HexOrientation};
@ -19,17 +24,27 @@ pub struct Tile;
#[reflect(Component)]
pub struct Wall;
/// Configuration for a single maze instance.
///
/// Contains all necessary parameters to generate and position a maze,
/// including its size, start/end positions, random seed, and layout.
#[derive(Debug, Reflect, Component, Clone)]
#[reflect(Component)]
pub struct MazeConfig {
/// Radius of the hexagonal maze
pub radius: u16,
/// Starting position in hex coordinates
pub start_pos: Hex,
/// Ending position in hex coordinates
pub end_pos: Hex,
/// Random seed for maze generation
pub seed: u64,
/// Layout configuration for hex-to-world space conversion
pub layout: HexLayout,
}
impl MazeConfig {
/// Creates a new maze configuration with the specified parameters.
fn new(
radius: u16,
orientation: HexOrientation,
@ -71,6 +86,7 @@ impl MazeConfig {
}
}
/// Updates the maze configuration with new global settings.
pub fn update(&mut self, global_conig: &GlobalMazeConfig) {
self.layout.hex_size = Vec2::splat(global_conig.hex_size);
}
@ -88,6 +104,10 @@ impl Default for MazeConfig {
}
}
/// Generates a random position within a hexagonal radius.
///
/// # Returns
/// A valid Hex coordinate within the specified radius
fn generate_pos<R: Rng>(radius: u16, rng: &mut R) -> Hex {
let radius = radius as i32;
loop {

View File

@ -1,10 +1,23 @@
use crate::maze::{
components::MazeConfig,
errors::{MazeError, MazeResult},
};
//! Common maze generation utilities.
use crate::maze::{components::MazeConfig, errors::MazeError};
use hexlab::prelude::*;
pub fn generate_maze(config: &MazeConfig) -> MazeResult<Maze> {
/// Generates a new maze based on the provided configuration.
///
/// This function uses a recursive backtracking algorithm to generate
/// a hexagonal maze with the specified parameters.
///
/// # Arguments
/// - `config` - Configuration parameters for maze generation including radius and seed.
///
/// # Returns
/// `Result<Maze, MazeError>` - The generated maze or an error if generation fails.
///
/// # Errors
/// Returns `MazeError::GenerationFailed` if:
/// - The maze builder fails to create a valid maze
/// - The provided radius or seed results in an invalid configuration
pub fn generate_maze(config: &MazeConfig) -> Result<Maze, MazeError> {
MazeBuilder::new()
.with_radius(config.radius)
.with_seed(config.seed)

View File

@ -1,7 +1,13 @@
//! Maze despawning functionality.
//!
//! Module handles the cleanup of maze entities when they need to be removed,
//! ensuring proper cleanup of both the maze and all its child entities.
use crate::{floor::components::Floor, maze::events::DespawnMaze};
use bevy::prelude::*;
pub(super) fn despawn_maze(
/// Despawns a maze and all its associated entities for a given floor.
pub fn despawn_maze(
trigger: Trigger<DespawnMaze>,
mut commands: Commands,
query: Query<(Entity, &Floor)>,

View File

@ -1,3 +1,8 @@
//! Maze respawning functionality.
//!
//! Module provides the ability to regenerate mazes for existing floors,
//! maintaining the same floor entity but replacing its internal maze structure.
use super::{common::generate_maze, spawn::spawn_maze_tiles};
use crate::{
floor::components::Floor,
@ -6,7 +11,15 @@ use crate::{
use bevy::prelude::*;
use hexlab::Maze;
pub(super) fn respawn_maze(
/// Respawns a maze for an existing floor with a new configuration.
///
/// # Behavior:
/// - Finds the target floor
/// - Generates a new maze configuration
/// - Cleans up existing maze tiles
/// - Spawns new maze tiles
/// - Updates the floor's configuration
pub fn respawn_maze(
trigger: Trigger<RespawnMaze>,
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,

View File

@ -1,3 +1,7 @@
//! Maze spawning and rendering functionality.
//!
//! Module handles the creation and visualization of hexagonal mazes.
use super::common::generate_maze;
use crate::{
constants::FLOOR_Y_OFFSET,
@ -20,6 +24,7 @@ use hexlab::prelude::{Tile as HexTile, *};
use hexx::HexOrientation;
use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
/// Spawns a new maze for the specified floor on [`SpawnMaze`] event.
pub fn spawn_maze(
trigger: Trigger<SpawnMaze>,
mut commands: Commands,
@ -44,9 +49,10 @@ pub fn spawn_maze(
}
};
// Calculate vertical offset based on floor number
let y_offset = match *floor {
1 => 0,
_ => FLOOR_Y_OFFSET,
1 => 0, // Ground/Initial floor (floor 1) is at y=0
_ => FLOOR_Y_OFFSET, // Other floors are offset vertically
} as f32;
let entity = commands
@ -60,7 +66,7 @@ pub fn spawn_maze(
Visibility::Visible,
StateScoped(Screen::Gameplay),
))
.insert_if(CurrentFloor, || *floor == 1)
.insert_if(CurrentFloor, || *floor == 1) // Only floor 1 gets CurrentFloor
.id();
let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config);
@ -79,6 +85,7 @@ pub fn spawn_maze(
}
}
/// Spawns all tiles for a maze as children of the parent maze entity
pub fn spawn_maze_tiles(
commands: &mut Commands,
parent_entity: Entity,
@ -94,6 +101,7 @@ pub fn spawn_maze_tiles(
});
}
/// Spawns a single hexagonal tile with appropriate transforms and materials
pub(super) fn spawn_single_hex_tile(
parent: &mut ChildBuilder,
assets: &MazeAssets,
@ -107,6 +115,7 @@ pub(super) fn spawn_single_hex_tile(
HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation
};
// Select material based on tile position: start, end, or default
let material = match tile.pos() {
pos if pos == maze_config.start_pos => assets
.custom_materials
@ -132,12 +141,14 @@ pub(super) fn spawn_single_hex_tile(
.with_children(|parent| spawn_walls(parent, assets, tile.walls(), global_config));
}
/// Spawns walls around a hexagonal tile based on the walls configuration
fn spawn_walls(
parent: &mut ChildBuilder,
assets: &MazeAssets,
walls: &Walls,
global_config: &GlobalMazeConfig,
) {
// Base rotation for wall alignment (90 degrees counter-clockwise)
let z_rotation = Quat::from_rotation_z(-FRAC_PI_2);
let y_offset = global_config.height / 2.;
@ -146,12 +157,25 @@ fn spawn_walls(
continue;
}
// Calculate the angle for this wall
// FRAC_PI_3 = 60 deg
// Negative because going clockwise
// i * 60 produces: 0, 60, 120, 180, 240, 300
let wall_angle = -FRAC_PI_3 * i as f32;
// cos(angle) gives x coordinate on unit circle
// sin(angle) gives z coordinate on unit circle
// Multiply by wall_offset to get actual distance from center
let x_offset = global_config.wall_offset() * f32::cos(wall_angle);
let z_offset = global_config.wall_offset() * f32::sin(wall_angle);
// x: distance along x-axis from center
// y: vertical offset from center
// z: distance along z-axis from center
let pos = Vec3::new(x_offset, y_offset, z_offset);
// 1. Rotate around x-axis to align wall with angle
// 2. Add FRAC_PI_2 (90) to make wall perpendicular to angle
let x_rotation = Quat::from_rotation_x(wall_angle + FRAC_PI_2);
let final_rotation = z_rotation * x_rotation;
@ -159,6 +183,7 @@ fn spawn_walls(
}
}
/// Spawns a single wall segment with the specified rotation and position
fn spawn_single_wall(parent: &mut ChildBuilder, assets: &MazeAssets, rotation: Quat, offset: Vec3) {
parent.spawn((
Name::new("Wall"),

View File

@ -1,13 +1,22 @@
//! Player movement system and related utilities.
//!
//! This module handles smooth player movement between hexagonal tiles,
//! including position interpolation and movement completion detection.
use crate::{
constants::MOVEMENT_THRESHOLD,
floor::components::CurrentFloor,
maze::components::MazeConfig,
player::components::{CurrentPosition, MovementSpeed, MovementTarget, Player},
};
use bevy::prelude::*;
use hexx::Hex;
pub(super) fn player_movement(
/// System handles player movement between hexagonal tiles.
///
/// Smoothly interpolates player position between hexagonal tiles,
/// handling movement target acquisition, position updates, and movement completion.
pub fn player_movement(
time: Res<Time>,
mut query: Query<
(
@ -48,10 +57,12 @@ pub(super) fn player_movement(
}
}
/// Determines if the movement should be completed based on proximity to target.
fn should_complete_movement(current_pos: Vec3, target_pos: Vec3) -> bool {
(target_pos - current_pos).length() < MOVEMENT_THRESHOLD
}
/// Updates the player's position based on movement parameters.
fn update_position(
transform: &mut Transform,
current_pos: Vec3,
@ -69,6 +80,7 @@ fn update_position(
transform.translation += movement;
}
/// Calculates the world position for a given hex coordinate.
fn calculate_target_position(maze_config: &MazeConfig, target_hex: Hex, y: f32) -> Vec3 {
let world_pos = maze_config.layout.hex_to_world_pos(target_hex);
Vec3::new(world_pos.x, y, world_pos.y)

View File

@ -1,4 +1,8 @@
use bevy::prelude::*;
//! Floor transition handling system.
//!
//! This module manages player transitions between different maze floors,
//! handling both ascending and descending movements based on player position
//! and input.
use crate::{
floor::{
@ -9,6 +13,12 @@ use crate::{
player::components::{CurrentPosition, Player},
};
use bevy::prelude::*;
/// Handles floor transitions when a player reaches start/end positions.
///
/// System checks if the player is at a valid transition point (start or end position)
/// and triggers floor transitions when the appropriate input is received.
pub fn handle_floor_transition(
mut player_query: Query<&CurrentPosition, With<Player>>,
maze_query: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
@ -25,13 +35,13 @@ pub fn handle_floor_transition(
};
for current_hex in player_query.iter_mut() {
// Check for ascending
// Check for ascending (at end position)
if current_hex.0 == config.end_pos {
info!("Ascending");
event_writer.send(TransitionFloor::Ascend);
}
// Check for descending
// Check for descending (at start position, not on first floor)
if current_hex.0 == config.start_pos && floor.0 != 1 {
info!("Descending");
event_writer.send(TransitionFloor::Descend);