From 1c01feee27cafc8d39a333794fd7f31ed845ff75 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 5 Jan 2025 17:44:51 +0200 Subject: [PATCH 1/5] chore(screen): delete Credits screen --- docs/design.md | 1 - src/lib.rs | 3 -- src/player/systems/input.rs | 1 + src/screens/credits.rs | 71 ------------------------------------- src/screens/loading.rs | 5 ++- src/screens/mod.rs | 3 -- src/screens/title.rs | 5 --- 7 files changed, 3 insertions(+), 86 deletions(-) delete mode 100644 src/screens/credits.rs diff --git a/docs/design.md b/docs/design.md index 8596511..84008b7 100644 --- a/docs/design.md +++ b/docs/design.md @@ -309,7 +309,6 @@ pub enum Screen { Splash, Loading, Title, - Credits, Gameplay, Victory, Leaderboard, diff --git a/src/lib.rs b/src/lib.rs index da23fd1..63f483c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,9 +103,6 @@ fn spawn_camera(mut commands: Commands) { } fn load_background(mut commands: Commands) { - #[cfg(feature = "dev")] - let colorcheme = rose_pine::RosePine::Base; - #[cfg(not(feature = "dev"))] let colorcheme = rose_pine::RosePineDawn::Base; commands.insert_resource(ClearColor(colorcheme.to_color())); } diff --git a/src/player/systems/input.rs b/src/player/systems/input.rs index 74f81f6..5c0e5af 100644 --- a/src/player/systems/input.rs +++ b/src/player/systems/input.rs @@ -222,6 +222,7 @@ impl From for EdgeDirection { direction.rotate_cw(0) } } + #[cfg(test)] mod tests { use super::*; diff --git a/src/screens/credits.rs b/src/screens/credits.rs deleted file mode 100644 index 44c23d8..0000000 --- a/src/screens/credits.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! A credits screen that can be accessed from the title screen. - -use bevy::prelude::*; - -use crate::{asset_tracking::LoadResource, audio::Music, screens::Screen, theme::prelude::*}; - -pub(super) fn plugin(app: &mut App) { - app.add_systems(OnEnter(Screen::Credits), spawn_credits_screen); - - app.load_resource::(); - app.add_systems(OnEnter(Screen::Credits), play_credits_music); - app.add_systems(OnExit(Screen::Credits), stop_music); -} - -fn spawn_credits_screen(mut commands: Commands) { - commands - .ui_root() - .insert(StateScoped(Screen::Credits)) - .with_children(|children| { - children.header("Made by"); - children.label("Joe Shmoe - Implemented aligator wrestling AI"); - children.label("Jane Doe - Made the music for the alien invasion"); - - children.header("Assets"); - children.label("Bevy logo - All rights reserved by the Bevy Foundation. Permission granted for splash screen use when unmodified."); - children.label("Ducky sprite - CC0 by Caz Creates Games"); - children.label("Button SFX - CC0 by Jaszunio15"); - children.label("Music - CC BY 3.0 by Kevin MacLeod"); - - children.button("Back").observe(enter_title_screen); - }); -} - -fn enter_title_screen(_trigger: Trigger, mut next_screen: ResMut>) { - next_screen.set(Screen::Title); -} - -#[derive(Resource, Asset, Reflect, Clone)] -pub struct CreditsMusic { - #[dependency] - music: Handle, - entity: Option, -} - -impl FromWorld for CreditsMusic { - fn from_world(world: &mut World) -> Self { - let assets = world.resource::(); - Self { - music: assets.load("audio/music/Monkeys Spinning Monkeys.ogg"), - entity: None, - } - } -} - -fn play_credits_music(mut commands: Commands, mut music: ResMut) { - music.entity = Some( - commands - .spawn(( - AudioPlayer::(music.music.clone()), - PlaybackSettings::LOOP, - Music, - )) - .id(), - ); -} - -fn stop_music(mut commands: Commands, mut music: ResMut) { - if let Some(entity) = music.entity.take() { - commands.entity(entity).despawn_recursive(); - } -} diff --git a/src/screens/loading.rs b/src/screens/loading.rs index 556c9a4..ebfdc2f 100644 --- a/src/screens/loading.rs +++ b/src/screens/loading.rs @@ -4,7 +4,7 @@ use bevy::prelude::*; use crate::{ - screens::{credits::CreditsMusic, gameplay::GameplayMusic, Screen}, + screens::{gameplay::GameplayMusic, Screen}, theme::{interaction::InteractionAssets, prelude::*}, }; @@ -35,8 +35,7 @@ fn continue_to_title_screen(mut next_screen: ResMut>) { const fn all_assets_loaded( interaction_assets: Option>, - credits_music: Option>, gameplay_music: Option>, ) -> bool { - interaction_assets.is_some() && credits_music.is_some() && gameplay_music.is_some() + interaction_assets.is_some() && gameplay_music.is_some() } diff --git a/src/screens/mod.rs b/src/screens/mod.rs index 13606fd..df0e70d 100644 --- a/src/screens/mod.rs +++ b/src/screens/mod.rs @@ -1,6 +1,5 @@ //! The game's main screen states and transitions between them. -mod credits; mod gameplay; mod loading; mod splash; @@ -13,7 +12,6 @@ pub(super) fn plugin(app: &mut App) { app.enable_state_scoped_entities::(); app.add_plugins(( - credits::plugin, gameplay::plugin, loading::plugin, splash::plugin, @@ -29,6 +27,5 @@ pub enum Screen { #[cfg_attr(feature = "dev", default)] Loading, Title, - Credits, Gameplay, } diff --git a/src/screens/title.rs b/src/screens/title.rs index 9b0457d..c56bba4 100644 --- a/src/screens/title.rs +++ b/src/screens/title.rs @@ -14,7 +14,6 @@ fn spawn_title_screen(mut commands: Commands) { .insert(StateScoped(Screen::Title)) .with_children(|children| { children.button("Play").observe(enter_gameplay_screen); - children.button("Credits").observe(enter_credits_screen); #[cfg(not(target_family = "wasm"))] children.button("Exit").observe(exit_app); @@ -25,10 +24,6 @@ fn enter_gameplay_screen(_trigger: Trigger, mut next_screen: ResMut, mut next_screen: ResMut>) { - next_screen.set(Screen::Credits); -} - #[cfg(not(target_family = "wasm"))] fn exit_app(_trigger: Trigger, mut app_exit: EventWriter) { app_exit.send(AppExit::Success); From f117dd5e1c21c652d538759fc80715083a295d68 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 5 Jan 2025 18:20:29 +0200 Subject: [PATCH 2/5] feat(UI): add title --- src/constants.rs | 1 + src/lib.rs | 3 ++- src/screens/loading.rs | 4 +-- src/screens/title.rs | 7 ++--- src/theme/palette/mod.rs | 9 ------- src/theme/widgets.rs | 58 ++++++++++++++++++++++------------------ 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index e806040..49c1203 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -2,3 +2,4 @@ pub const MOVEMENT_THRESHOLD: f32 = 0.01; pub const WALL_OVERLAP_MODIFIER: f32 = 1.25; pub const FLOOR_Y_OFFSET: u8 = 200; pub const MOVEMENT_COOLDOWN: f32 = 1.0; // one second cooldown +pub const TITLE: &'static str = "Maze Ascension: The Labyrinth of Echoes"; diff --git a/src/lib.rs b/src/lib.rs index 63f483c..1a03a18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ use bevy::{ audio::{AudioPlugin, Volume}, prelude::*, }; +use constants::TITLE; use theme::{palette::rose_pine, prelude::ColorScheme}; pub struct AppPlugin; @@ -41,7 +42,7 @@ impl Plugin for AppPlugin { }) .set(WindowPlugin { primary_window: Window { - title: "Maze Ascension: The Labyrinth of Echoes".to_string(), + title: TITLE.to_string(), canvas: Some("#bevy".to_string()), fit_canvas_to_parent: true, prevent_default_event_handling: true, diff --git a/src/screens/loading.rs b/src/screens/loading.rs index ebfdc2f..d77076e 100644 --- a/src/screens/loading.rs +++ b/src/screens/loading.rs @@ -21,8 +21,8 @@ fn spawn_loading_screen(mut commands: Commands) { commands .ui_root() .insert(StateScoped(Screen::Loading)) - .with_children(|children| { - children.label("Loading...").insert(Node { + .with_children(|parent| { + parent.label("Loading...").insert(Node { justify_content: JustifyContent::Center, ..default() }); diff --git a/src/screens/title.rs b/src/screens/title.rs index c56bba4..a4254d1 100644 --- a/src/screens/title.rs +++ b/src/screens/title.rs @@ -12,11 +12,12 @@ fn spawn_title_screen(mut commands: Commands) { commands .ui_root() .insert(StateScoped(Screen::Title)) - .with_children(|children| { - children.button("Play").observe(enter_gameplay_screen); + .with_children(|parent| { + parent.header("Maze Ascension"); + parent.button("Play").observe(enter_gameplay_screen); #[cfg(not(target_family = "wasm"))] - children.button("Exit").observe(exit_app); + parent.button("Quit").observe(exit_app); }); } diff --git a/src/theme/palette/mod.rs b/src/theme/palette/mod.rs index 8a3de0a..5718665 100644 --- a/src/theme/palette/mod.rs +++ b/src/theme/palette/mod.rs @@ -2,15 +2,6 @@ pub mod rose_pine; use bevy::prelude::*; -pub const BUTTON_HOVERED_BACKGROUND: Color = Color::srgb(0.186, 0.328, 0.573); -pub const BUTTON_PRESSED_BACKGROUND: Color = Color::srgb(0.286, 0.478, 0.773); - -pub const BUTTON_TEXT: Color = Color::srgb(0.925, 0.925, 0.925); -pub const LABEL_TEXT: Color = Color::srgb(0.867, 0.827, 0.412); -pub const HEADER_TEXT: Color = Color::srgb(0.867, 0.827, 0.412); - -pub const NODE_BACKGROUND: Color = Color::srgb(0.286, 0.478, 0.773); - const MAX_COLOR_VALUE: f32 = 255.; pub(super) const fn rgb_u8(red: u8, green: u8, blue: u8) -> Color { diff --git a/src/theme/widgets.rs b/src/theme/widgets.rs index bedf42a..1c1b0bc 100644 --- a/src/theme/widgets.rs +++ b/src/theme/widgets.rs @@ -1,9 +1,12 @@ //! Helper traits for creating common widgets. use bevy::{ecs::system::EntityCommands, prelude::*, ui::Val::*}; +use rose_pine::RosePineDawn; use crate::theme::{interaction::InteractionPalette, palette::*}; +use super::prelude::ColorScheme; + /// An extension trait for spawning UI widgets. pub trait Widgets { /// Spawn a simple button with text. @@ -22,7 +25,7 @@ impl Widgets for T { Name::new("Button"), Button, ImageNode { - color: NODE_BACKGROUND, + color: RosePineDawn::Surface.to_color(), ..default() }, Node { @@ -30,23 +33,26 @@ impl Widgets for T { height: Px(65.0), justify_content: JustifyContent::Center, align_items: AlignItems::Center, + border: UiRect::all(Px(4.)), ..default() }, + BorderRadius::all(Px(8.)), + BorderColor(RosePineDawn::Text.to_color()), InteractionPalette { - none: NODE_BACKGROUND, - hovered: BUTTON_HOVERED_BACKGROUND, - pressed: BUTTON_PRESSED_BACKGROUND, + none: RosePineDawn::HighlightLow.to_color(), + hovered: RosePineDawn::HighlightMed.to_color(), + pressed: RosePineDawn::HighlightHigh.to_color(), }, )); - entity.with_children(|children| { - children.spawn_ui(( + entity.with_children(|parent| { + parent.spawn_ui(( Name::new("Button Text"), Text(text.into()), TextFont { font_size: 40.0, ..default() }, - TextColor(BUTTON_TEXT), + TextColor(RosePineDawn::Text.to_color()), )); }); @@ -63,38 +69,38 @@ impl Widgets for T { align_items: AlignItems::Center, ..default() }, - BackgroundColor(NODE_BACKGROUND), )); - entity.with_children(|children| { - children.spawn_ui(( + entity.with_children(|parent| { + parent.spawn_ui(( Name::new("Header Text"), Text(text.into()), TextFont { - font_size: 40.0, + font_size: 60.0, ..default() }, - TextColor(HEADER_TEXT), + TextLayout { + justify: JustifyText::Center, + ..default() + }, + TextColor(RosePineDawn::Text.to_color()), )); }); entity } - fn label(&mut self, _text: impl Into) -> EntityCommands { + fn label(&mut self, text: impl Into) -> EntityCommands { let entity = self.spawn_ui(( Name::new("Label"), - Text::default(), - // TextBundle::from_section( - // text, - // TextStyle { - // font_size: 24.0, - // color: LABEL_TEXT, - // ..default() - // }, - // ) - // .with_style(Style { - // width: Px(500.0), - // ..default() - // }), + Text(text.into()), + TextFont { + font_size: 24.0, + ..default() + }, + TextColor(RosePineDawn::Text.to_color()), + Node { + width: Px(500.), + ..default() + }, )); entity } From 101626cf3d7b1044365c62bb189204020afea01b Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 5 Jan 2025 18:29:16 +0200 Subject: [PATCH 3/5] feat(UI): style header --- src/screens/title.rs | 9 ++++++++- src/theme/widgets.rs | 5 ++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/screens/title.rs b/src/screens/title.rs index a4254d1..8604beb 100644 --- a/src/screens/title.rs +++ b/src/screens/title.rs @@ -13,7 +13,14 @@ fn spawn_title_screen(mut commands: Commands) { .ui_root() .insert(StateScoped(Screen::Title)) .with_children(|parent| { - parent.header("Maze Ascension"); + parent + .spawn(Node { + bottom: Val::Px(70.), + ..default() + }) + .with_children(|parent| { + parent.header("Maze Ascension"); + }); parent.button("Play").observe(enter_gameplay_screen); #[cfg(not(target_family = "wasm"))] diff --git a/src/theme/widgets.rs b/src/theme/widgets.rs index 1c1b0bc..85f1962 100644 --- a/src/theme/widgets.rs +++ b/src/theme/widgets.rs @@ -3,9 +3,8 @@ use bevy::{ecs::system::EntityCommands, prelude::*, ui::Val::*}; use rose_pine::RosePineDawn; -use crate::theme::{interaction::InteractionPalette, palette::*}; - use super::prelude::ColorScheme; +use crate::theme::{interaction::InteractionPalette, palette::*}; /// An extension trait for spawning UI widgets. pub trait Widgets { @@ -123,7 +122,7 @@ impl Containers for Commands<'_, '_> { justify_content: JustifyContent::Center, align_items: AlignItems::Center, flex_direction: FlexDirection::Column, - row_gap: Px(10.0), + row_gap: Px(32.0), position_type: PositionType::Absolute, ..default() }, From 3709bfa58d755170bd1f85b2ebaea3591988d536 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 5 Jan 2025 18:39:20 +0200 Subject: [PATCH 4/5] refactor: remove MazePluginLoaded resource --- src/dev_tools/ui/maze_controls.rs | 10 +++++++--- src/floor/systems/mod.rs | 4 ++-- src/maze/mod.rs | 3 +-- src/maze/resources.rs | 4 ---- src/maze/triggers/spawn.rs | 2 ++ src/player/systems/mod.rs | 4 ++-- src/player/triggers/spawn.rs | 2 ++ 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/dev_tools/ui/maze_controls.rs b/src/dev_tools/ui/maze_controls.rs index 6f68b9a..4c64dfc 100644 --- a/src/dev_tools/ui/maze_controls.rs +++ b/src/dev_tools/ui/maze_controls.rs @@ -1,7 +1,8 @@ use crate::{ floor::components::{CurrentFloor, Floor}, - maze::{components::MazeConfig, events::RespawnMaze, GlobalMazeConfig, MazePluginLoaded}, + maze::{components::MazeConfig, events::RespawnMaze, GlobalMazeConfig}, player::events::RespawnPlayer, + screens::Screen, }; use bevy::{prelude::*, window::PrimaryWindow}; use bevy_egui::{ @@ -13,8 +14,11 @@ use rand::{thread_rng, Rng}; use std::ops::RangeInclusive; pub fn maze_controls_ui(world: &mut World) { - if world.get_resource::().is_none() { - return; + if let Some(state) = world.get_resource::>() { + // Check if the current state is NOT Gameplay + if *state.get() != Screen::Gameplay { + return; + } } let Ok(egui_context) = world diff --git a/src/floor/systems/mod.rs b/src/floor/systems/mod.rs index 43c50b2..5243719 100644 --- a/src/floor/systems/mod.rs +++ b/src/floor/systems/mod.rs @@ -2,7 +2,7 @@ mod despawn; mod movement; mod spawn; -use crate::maze::MazePluginLoaded; +use crate::screens::Screen; use bevy::prelude::*; use despawn::despawn_floor; use movement::{handle_floor_transition_events, move_floors}; @@ -18,6 +18,6 @@ pub(super) fn plugin(app: &mut App) { move_floors, ) .chain() - .run_if(resource_exists::), + .run_if(in_state(Screen::Gameplay)), ); } diff --git a/src/maze/mod.rs b/src/maze/mod.rs index b2a30e2..e8f9481 100644 --- a/src/maze/mod.rs +++ b/src/maze/mod.rs @@ -9,7 +9,7 @@ pub mod triggers; use bevy::{ecs::system::RunSystemOnce, prelude::*}; use components::HexMaze; use events::{DespawnMaze, RespawnMaze, SpawnMaze}; -pub use resources::{GlobalMazeConfig, MazePluginLoaded}; +pub use resources::GlobalMazeConfig; pub(super) fn plugin(app: &mut App) { app.init_resource::() @@ -22,5 +22,4 @@ pub(super) fn plugin(app: &mut App) { pub fn spawn_level_command(world: &mut World) { let _ = world.run_system_once(systems::setup::setup); - world.insert_resource(MazePluginLoaded); } diff --git a/src/maze/resources.rs b/src/maze/resources.rs index 7aeee09..190ec8b 100644 --- a/src/maze/resources.rs +++ b/src/maze/resources.rs @@ -1,9 +1,5 @@ use bevy::prelude::*; -#[derive(Debug, Default, Reflect, Resource)] -#[reflect(Resource)] -pub struct MazePluginLoaded; - #[derive(Debug, Reflect, Resource, Clone)] #[reflect(Resource)] pub struct GlobalMazeConfig { diff --git a/src/maze/triggers/spawn.rs b/src/maze/triggers/spawn.rs index b9b930f..c8ab16d 100644 --- a/src/maze/triggers/spawn.rs +++ b/src/maze/triggers/spawn.rs @@ -8,6 +8,7 @@ use crate::{ events::SpawnMaze, resources::GlobalMazeConfig, }, + screens::Screen, theme::palette::rose_pine::RosePineDawn, }; @@ -53,6 +54,7 @@ pub(crate) fn spawn_maze( config.clone(), Transform::from_translation(Vec3::ZERO.with_y(y_offset)), Visibility::Visible, + StateScoped(Screen::Gameplay), )) .insert_if(CurrentFloor, || *floor == 1) .id(); diff --git a/src/player/systems/mod.rs b/src/player/systems/mod.rs index c71e33d..9e892ea 100644 --- a/src/player/systems/mod.rs +++ b/src/player/systems/mod.rs @@ -3,7 +3,7 @@ mod movement; pub mod setup; mod vertical_transition; -use crate::maze::MazePluginLoaded; +use crate::screens::Screen; use bevy::prelude::*; use input::player_input; use movement::player_movement; @@ -17,6 +17,6 @@ pub(super) fn plugin(app: &mut App) { player_movement.after(player_input), handle_floor_transition, ) - .run_if(resource_exists::), + .run_if(in_state(Screen::Gameplay)), ); } diff --git a/src/player/triggers/spawn.rs b/src/player/triggers/spawn.rs index 5c77171..00bbdd0 100644 --- a/src/player/triggers/spawn.rs +++ b/src/player/triggers/spawn.rs @@ -6,6 +6,7 @@ use crate::{ components::{CurrentPosition, Player}, events::SpawnPlayer, }, + screens::Screen, }; use bevy::prelude::*; @@ -34,5 +35,6 @@ pub(super) fn spawn_player( Mesh3d(meshes.add(generate_pill_mesh(player_radius, player_height / 2.))), MeshMaterial3d(materials.add(blue_material())), Transform::from_xyz(start_pos.x, y_offset, start_pos.y), + StateScoped(Screen::Gameplay), )); } From 35e6420e68593cbee9f9b8af5d8186df687ffe9f Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 5 Jan 2025 18:47:23 +0200 Subject: [PATCH 5/5] chore(maze): change default maze radius --- src/floor/systems/spawn.rs | 2 +- src/maze/components.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/floor/systems/spawn.rs b/src/floor/systems/spawn.rs index 445a12f..e59cfbb 100644 --- a/src/floor/systems/spawn.rs +++ b/src/floor/systems/spawn.rs @@ -33,7 +33,7 @@ pub(super) fn spawn_floor( floor: target_floor, config: MazeConfig { start_pos: config.end_pos, - radius: config.radius + 2, + radius: config.radius + 1, ..default() }, }); diff --git a/src/maze/components.rs b/src/maze/components.rs index 1bd7f8a..c3731d2 100644 --- a/src/maze/components.rs +++ b/src/maze/components.rs @@ -79,7 +79,7 @@ impl MazeConfig { impl Default for MazeConfig { fn default() -> Self { Self::new( - 8, + 4, HexOrientation::Flat, None, &GlobalMazeConfig::default(), @@ -93,7 +93,6 @@ fn generate_pos(radius: u16, rng: &mut R) -> Hex { loop { let q = rng.gen_range(-radius..=radius); let r = rng.gen_range(-radius..=radius); - let s = -q - r; // Calculate third coordinate (axial coordinates: q + r + s = 0) // Check if the position is within the hexagonal radius