From ad1c2efc42c53d53a7f839fa41a30ee9c1cd5a0c Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Sun, 25 Feb 2024 22:07:44 -0600 Subject: [PATCH 01/22] replace image prompt with ui button --- src/ui/main_menu.rs | 59 +++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/ui/main_menu.rs b/src/ui/main_menu.rs index dbdb2f81..242f15f5 100644 --- a/src/ui/main_menu.rs +++ b/src/ui/main_menu.rs @@ -9,11 +9,12 @@ use bevy::{ hierarchy::BuildChildren, render::color::Color, text::{JustifyText, Text, TextStyle}, - time::{Time, Timer, TimerMode}, + time::{Time, Timer}, transform::components::Transform, ui::{ - node_bundles::{ImageBundle, NodeBundle, TextBundle}, - BackgroundColor, FlexDirection, JustifyContent, Style, UiRect, Val, + node_bundles::{ButtonBundle, ImageBundle, NodeBundle, TextBundle}, + AlignItems, BackgroundColor, BorderColor, FlexDirection, JustifyContent, Style, UiRect, + Val, }, utils::default, }; @@ -126,7 +127,7 @@ pub fn setup_main_menu_system( super::pprint_mob_kills_from_data(&historical_games_enemy_mob_kill_counts), ), TextStyle { - font, + font: font.clone(), font_size: 32.0, color: Color::WHITE, }, @@ -138,32 +139,32 @@ pub fn setup_main_menu_system( }); parent - .spawn(ImageBundle { - image: asset_server - .load(if **playing_on_arcade { - "texture/start_game_prompt_arcade.png" - } else { - "texture/start_game_prompt_keyboard.png" - }) - .into(), - style: Style { - width: Val::Px(400.0), - height: Val::Px(100.0), - margin: UiRect { - bottom: Val::Percent(10.0), - top: Val::Auto, - right: Val::Auto, - left: Val::Auto, + .spawn( + ButtonBundle { + style: Style { + width: Val::Px(250.0), + height: Val::Px(100.0), + border: UiRect::all(Val::Px(5.0)), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + /* */ + margin: UiRect { + bottom: Val::Percent(10.0), + top: Val::Auto, + right: Val::Auto, + left: Val::Auto, + }, + ..default() }, - justify_content: JustifyContent::Center, - ..Default::default() - }, - ..Default::default() - }) - .insert(BouncingPromptComponent { - flash_timer: Timer::from_seconds(2.0, TimerMode::Repeating), - is_active: true, - }); + border_color: BorderColor(Color::RED), + background_color: BackgroundColor(Color::GREEN), + ..default() + } + ).with_children(|parent|{ + parent.spawn(TextBundle::from_section("Start", TextStyle { font, font_size: 40.0, color: Color::WHITE })); + }); }); }); } From 818cc1d873f22aee05fb5c7b84cb09eae5dc609e Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Sun, 25 Feb 2024 23:08:06 -0600 Subject: [PATCH 02/22] add four ui buttons to main menu --- src/ui/main_menu.rs | 163 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 139 insertions(+), 24 deletions(-) diff --git a/src/ui/main_menu.rs b/src/ui/main_menu.rs index 242f15f5..02fe4797 100644 --- a/src/ui/main_menu.rs +++ b/src/ui/main_menu.rs @@ -91,6 +91,7 @@ pub fn setup_main_menu_system( .with_children(|parent| { let font = asset_server.load("fonts/wibletown-regular.otf"); + /* parent .spawn(NodeBundle { style: Style { @@ -111,6 +112,7 @@ pub fn setup_main_menu_system( ..default() }) .with_children(|parent| { + parent.spawn(TextBundle { style: Style { width: Val::Auto, @@ -137,34 +139,147 @@ pub fn setup_main_menu_system( ..default() }); }); + */ parent - .spawn( - ButtonBundle { - style: Style { - width: Val::Px(250.0), - height: Val::Px(100.0), - border: UiRect::all(Val::Px(5.0)), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - /* */ - margin: UiRect { - bottom: Val::Percent(10.0), - top: Val::Auto, - right: Val::Auto, - left: Val::Auto, - }, - ..default() + .spawn(ButtonBundle { + style: Style { + width: Val::Percent(20.0), + max_width: Val::Px(300.0), + min_height: Val::Percent(5.0), + border: UiRect::all(Val::Px(5.0)), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + /* */ + margin: UiRect { + bottom: Val::Percent(3.0), + top: Val::Percent(50.0), + right: Val::Auto, + left: Val::Auto, + }, + ..default() + }, + border_color: BorderColor(Color::RED), + background_color: BackgroundColor(Color::GREEN), + ..default() + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Start", + TextStyle { + font: font.clone(), + font_size: 40.0, + color: Color::WHITE, + }, + )); + }); + + parent + .spawn(ButtonBundle { + style: Style { + width: Val::Percent(20.0), + max_width: Val::Px(300.0), + min_height: Val::Percent(5.0), + border: UiRect::all(Val::Px(5.0)), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + /* */ + margin: UiRect { + bottom: Val::Percent(3.0), + top: Val::Auto, + right: Val::Auto, + left: Val::Auto, }, - border_color: BorderColor(Color::RED), - background_color: BackgroundColor(Color::GREEN), ..default() - } - ).with_children(|parent|{ - parent.spawn(TextBundle::from_section("Start", TextStyle { font, font_size: 40.0, color: Color::WHITE })); - }); + }, + border_color: BorderColor(Color::RED), + background_color: BackgroundColor(Color::GREEN), + ..default() + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Beastiary", + TextStyle { + font: font.clone(), + font_size: 40.0, + color: Color::WHITE, + }, + )); + }); + + parent + .spawn(ButtonBundle { + style: Style { + width: Val::Percent(20.0), + max_width: Val::Px(300.0), + min_height: Val::Percent(5.0), + border: UiRect::all(Val::Px(5.0)), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + /* */ + margin: UiRect { + bottom: Val::Percent(3.0), + top: Val::Auto, + right: Val::Auto, + left: Val::Auto, + }, + ..default() + }, + border_color: BorderColor(Color::RED), + background_color: BackgroundColor(Color::GREEN), + ..default() + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Options", + TextStyle { + font: font.clone(), + font_size: 40.0, + color: Color::WHITE, + }, + )); + }); + + parent + .spawn(ButtonBundle { + style: Style { + width: Val::Percent(20.0), + max_width: Val::Px(300.0), + min_height: Val::Percent(5.0), + border: UiRect::all(Val::Px(5.0)), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + /* */ + margin: UiRect { + bottom: Val::Percent(5.0), + top: Val::Auto, + right: Val::Auto, + left: Val::Auto, + }, + ..default() + }, + border_color: BorderColor(Color::RED), + background_color: BackgroundColor(Color::GREEN), + ..default() + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Quit", + TextStyle { + font: font.clone(), + font_size: 40.0, + color: Color::WHITE, + }, + )); + }); }); }); } From aa3a847e6b7a49f7e21267ed4103f0b12e68fafe Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Mon, 26 Feb 2024 17:51:22 -0600 Subject: [PATCH 03/22] add button ui module --- src/ui/button.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++ src/ui/main_menu.rs | 9 +++++++-- src/ui/mod.rs | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/ui/button.rs diff --git a/src/ui/button.rs b/src/ui/button.rs new file mode 100644 index 00000000..9650374d --- /dev/null +++ b/src/ui/button.rs @@ -0,0 +1,46 @@ +use bevy::{ + hierarchy::{BuildChildren, ChildBuilder}, + prelude::Component, + render::color::Color, + ui::{node_bundles::ButtonBundle, BackgroundColor, Style, UiRect}, + utils::default, +}; + +pub trait UIChildBuilderExt { + pub fn spawn_menu_button(&mut self, text: String); +} + +impl UIChildBuilderExt for ChildBuilder { + fn spawn_menu_button(&mut self, text: String) { + self.spawn(ButtonBundle { + style: Style { + width: Val::Percent(20.0), + max_width: Val::Px(300.0), + min_height: Val::Percent(5.0), + border: UiRect::all(Val::px(5.0)), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + margin: UiRect { + bottom: Val::Percent(3.0), + top: Val::Auto, + right: Val::Auto, + left: Val::Auto, + }, + ..default() + }, + border_color: BorderColor(Color::RED), + background_color: BackgroundColor(Color::GREEN), + ..default() + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + text, + TextStyle { + font: font.clone(), + font_size: 40.0, + color: Color::WHITE, + }, + )); + }); + } +} diff --git a/src/ui/main_menu.rs b/src/ui/main_menu.rs index 02fe4797..7c91f3a3 100644 --- a/src/ui/main_menu.rs +++ b/src/ui/main_menu.rs @@ -25,6 +25,8 @@ use thetawave_interface::game::historical_metrics::{ }; use thetawave_interface::states::MainMenuCleanup; +use super::button::UIChildBuilderExt; + #[derive(Component)] pub struct MainMenuUI; @@ -140,7 +142,7 @@ pub fn setup_main_menu_system( }); }); */ - + /* parent .spawn(ButtonBundle { style: Style { @@ -175,6 +177,9 @@ pub fn setup_main_menu_system( }, )); }); + */ + + parent.spawn_menu_button(String::from("Test")); parent .spawn(ButtonBundle { @@ -202,7 +207,7 @@ pub fn setup_main_menu_system( }) .with_children(|parent| { parent.spawn(TextBundle::from_section( - "Beastiary", + "Compendium", TextStyle { font: font.clone(), font_size: 40.0, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 4a727cc7..6fe2edee 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -19,6 +19,7 @@ mod pause_menu; mod phase; mod player; mod victory; +mod button; use self::character_selection::toggle_tutorial_system; pub use self::character_selection::{ From f5543cbe4d8b2f4a7cf3e1ac2e306326e047c394 Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Mon, 26 Feb 2024 22:48:22 -0600 Subject: [PATCH 04/22] adjust button style and load buttons from images --- src/options/display.rs | 2 +- src/ui/button.rs | 48 +++++++---------- src/ui/main_menu.rs | 114 ++--------------------------------------- src/ui/mod.rs | 2 +- 4 files changed, 26 insertions(+), 140 deletions(-) diff --git a/src/options/display.rs b/src/options/display.rs index e7526fe1..e93a1df7 100644 --- a/src/options/display.rs +++ b/src/options/display.rs @@ -23,7 +23,7 @@ impl From for Window { Window { title: "Thetawave".to_string(), resolution: (display_config.width, display_config.height).into(), - resizable: false, + resizable: true, mode: if display_config.fullscreen { WindowMode::SizedFullscreen } else { diff --git a/src/ui/button.rs b/src/ui/button.rs index 9650374d..1433df44 100644 --- a/src/ui/button.rs +++ b/src/ui/button.rs @@ -1,46 +1,36 @@ use bevy::{ - hierarchy::{BuildChildren, ChildBuilder}, - prelude::Component, - render::color::Color, - ui::{node_bundles::ButtonBundle, BackgroundColor, Style, UiRect}, + asset::Handle, + hierarchy::ChildBuilder, + render::texture::Image, + ui::{node_bundles::ButtonBundle, AlignItems, JustifyContent, Style, UiRect, Val}, utils::default, }; +const BUTTON_WIDTH: Val = Val::Percent(20.0); +const BUTTON_MAX_WIDTH: Val = Val::Px(500.0); +const BUTTON_MIN_WIDTH: Val = Val::Px(125.0); +const BUTTON_MARGIN: UiRect = + UiRect::new(Val::Auto, Val::Auto, Val::Percent(1.0), Val::Percent(1.0)); + pub trait UIChildBuilderExt { - pub fn spawn_menu_button(&mut self, text: String); + fn spawn_menu_button(&mut self, image: Handle); } -impl UIChildBuilderExt for ChildBuilder { - fn spawn_menu_button(&mut self, text: String) { +impl UIChildBuilderExt for ChildBuilder<'_> { + fn spawn_menu_button(&mut self, image: Handle) { self.spawn(ButtonBundle { style: Style { - width: Val::Percent(20.0), - max_width: Val::Px(300.0), - min_height: Val::Percent(5.0), - border: UiRect::all(Val::px(5.0)), + max_width: BUTTON_MAX_WIDTH, + width: BUTTON_WIDTH, + min_width: BUTTON_MIN_WIDTH, + aspect_ratio: Some(132.0 / 32.0), justify_content: JustifyContent::Center, align_items: AlignItems::Center, - margin: UiRect { - bottom: Val::Percent(3.0), - top: Val::Auto, - right: Val::Auto, - left: Val::Auto, - }, + margin: BUTTON_MARGIN, ..default() }, - border_color: BorderColor(Color::RED), - background_color: BackgroundColor(Color::GREEN), + image: image.into(), ..default() - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - text, - TextStyle { - font: font.clone(), - font_size: 40.0, - color: Color::WHITE, - }, - )); }); } } diff --git a/src/ui/main_menu.rs b/src/ui/main_menu.rs index 7c91f3a3..8f712be5 100644 --- a/src/ui/main_menu.rs +++ b/src/ui/main_menu.rs @@ -1,6 +1,6 @@ use crate::options::PlayingOnArcadeResource; use bevy::{ - asset::AssetServer, + asset::{self, AssetServer}, ecs::{ component::Component, event::EventWriter, @@ -91,8 +91,6 @@ pub fn setup_main_menu_system( ..default() }) .with_children(|parent| { - let font = asset_server.load("fonts/wibletown-regular.otf"); - /* parent .spawn(NodeBundle { @@ -179,112 +177,10 @@ pub fn setup_main_menu_system( }); */ - parent.spawn_menu_button(String::from("Test")); - - parent - .spawn(ButtonBundle { - style: Style { - width: Val::Percent(20.0), - max_width: Val::Px(300.0), - min_height: Val::Percent(5.0), - border: UiRect::all(Val::Px(5.0)), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - /* */ - margin: UiRect { - bottom: Val::Percent(3.0), - top: Val::Auto, - right: Val::Auto, - left: Val::Auto, - }, - ..default() - }, - border_color: BorderColor(Color::RED), - background_color: BackgroundColor(Color::GREEN), - ..default() - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Compendium", - TextStyle { - font: font.clone(), - font_size: 40.0, - color: Color::WHITE, - }, - )); - }); - - parent - .spawn(ButtonBundle { - style: Style { - width: Val::Percent(20.0), - max_width: Val::Px(300.0), - min_height: Val::Percent(5.0), - border: UiRect::all(Val::Px(5.0)), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - /* */ - margin: UiRect { - bottom: Val::Percent(3.0), - top: Val::Auto, - right: Val::Auto, - left: Val::Auto, - }, - ..default() - }, - border_color: BorderColor(Color::RED), - background_color: BackgroundColor(Color::GREEN), - ..default() - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Options", - TextStyle { - font: font.clone(), - font_size: 40.0, - color: Color::WHITE, - }, - )); - }); - - parent - .spawn(ButtonBundle { - style: Style { - width: Val::Percent(20.0), - max_width: Val::Px(300.0), - min_height: Val::Percent(5.0), - border: UiRect::all(Val::Px(5.0)), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - /* */ - margin: UiRect { - bottom: Val::Percent(5.0), - top: Val::Auto, - right: Val::Auto, - left: Val::Auto, - }, - ..default() - }, - border_color: BorderColor(Color::RED), - background_color: BackgroundColor(Color::GREEN), - ..default() - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Quit", - TextStyle { - font: font.clone(), - font_size: 40.0, - color: Color::WHITE, - }, - )); - }); + parent.spawn_menu_button(asset_server.load("texture/start_button.png")); + parent.spawn_menu_button(asset_server.load("texture/compendium_button.png")); + parent.spawn_menu_button(asset_server.load("texture/options_button.png")); + parent.spawn_menu_button(asset_server.load("texture/quit_button.png")); }); }); } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 6fe2edee..ece4af80 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -8,6 +8,7 @@ use thetawave_interface::game::historical_metrics::{MobsKilledByPlayerCacheT, DE use crate::GameEnterSet; use thetawave_interface::states; +mod button; mod character_selection; mod game; mod game_center; @@ -19,7 +20,6 @@ mod pause_menu; mod phase; mod player; mod victory; -mod button; use self::character_selection::toggle_tutorial_system; pub use self::character_selection::{ From 65899b72cda3065bd0df72d7e24c36fa18909710 Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Tue, 27 Feb 2024 01:59:03 -0600 Subject: [PATCH 05/22] add animated thetawave logo to titlescreen, adjust button layout --- assets/ui_assets.assets.ron | 9 +++ src/animation/mod.rs | 4 ++ src/assets/mod.rs | 5 +- src/assets/ui.rs | 13 ++++ src/states/mod.rs | 5 +- src/ui/button.rs | 8 +-- src/ui/main_menu.rs | 133 +++++++++++++----------------------- 7 files changed, 85 insertions(+), 92 deletions(-) create mode 100644 assets/ui_assets.assets.ron create mode 100644 src/assets/ui.rs diff --git a/assets/ui_assets.assets.ron b/assets/ui_assets.assets.ron new file mode 100644 index 00000000..f84b7273 --- /dev/null +++ b/assets/ui_assets.assets.ron @@ -0,0 +1,9 @@ +({ + "thetawave_logo.layout": TextureAtlasLayout ( + tile_size_x: 1920., + tile_size_y: 1080., + columns: 4, + rows: 12, + ), + "thetawave_logo.image": File( path: "texture/thetawave_logo_spritesheet.png"), +}) \ No newline at end of file diff --git a/src/animation/mod.rs b/src/animation/mod.rs index 69a860e0..6d51f5bb 100644 --- a/src/animation/mod.rs +++ b/src/animation/mod.rs @@ -24,6 +24,10 @@ impl Plugin for AnimationPlugin { animate_sprite_system .run_if(in_state(states::AppStates::Game)) .run_if(in_state(states::GameStates::Playing)), + ) + .add_systems( + Update, + animate_sprite_system.run_if(in_state(states::AppStates::MainMenu)), ); app.add_event::(); diff --git a/src/assets/mod.rs b/src/assets/mod.rs index 066c5811..e1b03841 100644 --- a/src/assets/mod.rs +++ b/src/assets/mod.rs @@ -5,5 +5,8 @@ mod item; mod mob; mod player; mod projectile; +mod ui; -pub use self::{audio::*, consumable::*, effect::*, item::*, mob::*, player::*, projectile::*}; +pub use self::{ + audio::*, consumable::*, effect::*, item::*, mob::*, player::*, projectile::*, ui::*, +}; diff --git a/src/assets/ui.rs b/src/assets/ui.rs new file mode 100644 index 00000000..ee99b0a7 --- /dev/null +++ b/src/assets/ui.rs @@ -0,0 +1,13 @@ +use bevy::{ + prelude::{Handle, Resource, TextureAtlasLayout}, + render::texture::Image, +}; +use bevy_asset_loader::prelude::AssetCollection; + +#[derive(AssetCollection, Resource)] +pub struct UiAssets { + #[asset(key = "thetawave_logo.layout")] + pub thetawave_logo_layout: Handle, + #[asset(key = "thetawave_logo.image")] + pub thetawave_logo_image: Handle, +} diff --git a/src/states/mod.rs b/src/states/mod.rs index 985eda0c..18985fd9 100644 --- a/src/states/mod.rs +++ b/src/states/mod.rs @@ -28,6 +28,7 @@ use crate::assets::ItemAssets; use crate::assets::MobAssets; use crate::assets::PlayerAssets; use crate::assets::ProjectileAssets; +use crate::assets::UiAssets; use crate::GameEnterSet; use crate::GameUpdateSet; @@ -60,13 +61,15 @@ impl Plugin for StatesPlugin { .with_dynamic_assets_file::( "game_audio_assets.assets.ron", ) + .with_dynamic_assets_file::("ui_assets.assets.ron") .load_collection::() .load_collection::() .load_collection::() .load_collection::() .load_collection::() .load_collection::() - .load_collection::(), + .load_collection::() + .load_collection::(), ); app.edit_schedule(OnEnter(AppStates::Game), |schedule| { diff --git a/src/ui/button.rs b/src/ui/button.rs index 1433df44..3f221cfa 100644 --- a/src/ui/button.rs +++ b/src/ui/button.rs @@ -6,17 +6,17 @@ use bevy::{ utils::default, }; -const BUTTON_WIDTH: Val = Val::Percent(20.0); +const BUTTON_WIDTH: Val = Val::Percent(25.0); const BUTTON_MAX_WIDTH: Val = Val::Px(500.0); -const BUTTON_MIN_WIDTH: Val = Val::Px(125.0); +const BUTTON_MIN_WIDTH: Val = Val::Px(200.0); const BUTTON_MARGIN: UiRect = UiRect::new(Val::Auto, Val::Auto, Val::Percent(1.0), Val::Percent(1.0)); -pub trait UIChildBuilderExt { +pub trait UiChildBuilderExt { fn spawn_menu_button(&mut self, image: Handle); } -impl UIChildBuilderExt for ChildBuilder<'_> { +impl UiChildBuilderExt for ChildBuilder<'_> { fn spawn_menu_button(&mut self, image: Handle) { self.spawn(ButtonBundle { style: Style { diff --git a/src/ui/main_menu.rs b/src/ui/main_menu.rs index 8f712be5..2e61c0f5 100644 --- a/src/ui/main_menu.rs +++ b/src/ui/main_menu.rs @@ -1,6 +1,9 @@ -use crate::options::PlayingOnArcadeResource; +use crate::{ + animation::{AnimationComponent, AnimationDirection}, + assets::UiAssets, +}; use bevy::{ - asset::{self, AssetServer}, + asset::AssetServer, ecs::{ component::Component, event::EventWriter, @@ -8,24 +11,22 @@ use bevy::{ }, hierarchy::BuildChildren, render::color::Color, - text::{JustifyText, Text, TextStyle}, - time::{Time, Timer}, + time::{Time, Timer, TimerMode}, transform::components::Transform, ui::{ - node_bundles::{ButtonBundle, ImageBundle, NodeBundle, TextBundle}, - AlignItems, BackgroundColor, BorderColor, FlexDirection, JustifyContent, Style, UiRect, - Val, + node_bundles::{AtlasImageBundle, NodeBundle}, + AlignItems, FlexDirection, JustifyContent, Style, Val, }, utils::default, }; use std::time::Duration; use thetawave_interface::audio::{BGMusicType, ChangeBackgroundMusicEvent}; use thetawave_interface::game::historical_metrics::{ - MobKillsByPlayerForCompletedGames, UserStatsByPlayerForCompletedGamesCache, DEFAULT_USER_ID, + UserStatsByPlayerForCompletedGamesCache, DEFAULT_USER_ID, }; use thetawave_interface::states::MainMenuCleanup; -use super::button::UIChildBuilderExt; +use super::button::UiChildBuilderExt; #[derive(Component)] pub struct MainMenuUI; @@ -41,8 +42,7 @@ pub fn setup_main_menu_system( asset_server: Res, mut change_bg_music_event_writer: EventWriter, historical_games_shot_counts: Res, - historical_games_enemy_mob_kill_counts: Res, - playing_on_arcade: Res, + ui_assets: Res, ) { let maybe_user_stats = (**historical_games_shot_counts).get(&DEFAULT_USER_ID); @@ -77,110 +77,71 @@ pub fn setup_main_menu_system( .insert(MainMenuUI) .with_children(|parent| { parent - .spawn(ImageBundle { - image: asset_server - .load("texture/main_menu_background_54.png") - .into(), + .spawn(NodeBundle { style: Style { width: Val::Percent(100.0), flex_direction: FlexDirection::Column, height: Val::Percent(100.0), - justify_content: JustifyContent::FlexEnd, + justify_content: JustifyContent::FlexStart, ..Default::default() }, ..default() }) .with_children(|parent| { - /* parent .spawn(NodeBundle { style: Style { - width: Val::Auto, - height: Val::Auto, - margin: UiRect { - bottom: Val::Auto, - top: Val::Percent(40.0), - right: Val::Auto, - left: Val::Auto, - }, - padding: UiRect::all(Val::Px(10.0)), - + width: Val::Percent(100.0), + height: Val::Percent(50.0), + flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, - ..Default::default() + align_items: AlignItems::Center, + ..default() }, - background_color: BackgroundColor::from(Color::BLACK.with_a(0.9)), ..default() }) .with_children(|parent| { - - parent.spawn(TextBundle { - style: Style { - width: Val::Auto, - height: Val::Auto, - margin: UiRect::all(Val::Auto), - ..Default::default() - }, - - text: Text::from_section( - format!( - "Projectiles fired: {}\nAccuracy: {:.2}%\n\nEnemies destroyed:\n{}", - total_shots_fired, - accuracy_rate, - super::pprint_mob_kills_from_data(&historical_games_enemy_mob_kill_counts), - ), - TextStyle { - font: font.clone(), - font_size: 32.0, - color: Color::WHITE, + parent + .spawn(AtlasImageBundle { + style: Style { + max_width: Val::Px(900.0), + width: Val::Percent(70.0), + min_width: Val::Px(300.0), + aspect_ratio: Some(1920.0 / 1080.0), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + ..default() }, - ) - .with_justify(JustifyText::Center), - - ..default() - }); + image: ui_assets.thetawave_logo_image.clone().into(), + texture_atlas: ui_assets.thetawave_logo_layout.clone().into(), + ..default() + }) + .insert(AnimationComponent { + timer: Timer::from_seconds(0.1, TimerMode::Repeating), + direction: AnimationDirection::Forward, + }); }); - */ - /* parent - .spawn(ButtonBundle { + .spawn(NodeBundle { style: Style { - width: Val::Percent(20.0), - max_width: Val::Px(300.0), - min_height: Val::Percent(5.0), - border: UiRect::all(Val::Px(5.0)), - // horizontally center child text + width: Val::Percent(100.0), + height: Val::Percent(50.0), + flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, - // vertically center child text align_items: AlignItems::Center, - /* */ - margin: UiRect { - bottom: Val::Percent(3.0), - top: Val::Percent(50.0), - right: Val::Auto, - left: Val::Auto, - }, ..default() }, - border_color: BorderColor(Color::RED), - background_color: BackgroundColor(Color::GREEN), ..default() }) .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Start", - TextStyle { - font: font.clone(), - font_size: 40.0, - color: Color::WHITE, - }, - )); + parent.spawn_menu_button(asset_server.load("texture/start_button.png")); + parent.spawn_menu_button( + asset_server.load("texture/compendium_button.png"), + ); + parent + .spawn_menu_button(asset_server.load("texture/options_button.png")); + parent.spawn_menu_button(asset_server.load("texture/quit_button.png")); }); - */ - - parent.spawn_menu_button(asset_server.load("texture/start_button.png")); - parent.spawn_menu_button(asset_server.load("texture/compendium_button.png")); - parent.spawn_menu_button(asset_server.load("texture/options_button.png")); - parent.spawn_menu_button(asset_server.load("texture/quit_button.png")); }); }); } From 06a483da4fbb1b4126852f5edd642a1190a9841f Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Tue, 27 Feb 2024 10:23:59 -0600 Subject: [PATCH 06/22] add backgrounds to main menu --- src/background/mod.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/background/mod.rs b/src/background/mod.rs index 5c71a092..73ab95f5 100644 --- a/src/background/mod.rs +++ b/src/background/mod.rs @@ -38,7 +38,7 @@ use std::ops::Range; use thetawave_interface::{ game::options::GameOptions, run::{RunDefeatType, RunEndEvent, RunOutcomeType}, - states::{self, GameCleanup}, + states::{self, GameCleanup, MainMenuCleanup}, }; use thiserror::Error; @@ -59,6 +59,16 @@ impl Plugin for BackgroundPlugin { create_background_system.in_set(GameEnterSet::BuildLevel), ); + app.add_systems( + OnEnter(states::AppStates::MainMenu), + create_background_system, + ); + + app.add_systems( + Update, + rotate_planet_system.run_if(in_state(states::AppStates::MainMenu)), + ); + app.add_systems( Update, (rotate_planet_system, on_defeat_star_explode_system) @@ -197,7 +207,8 @@ pub fn create_background_system( let mut rng = rand::thread_rng(); // Choose random positions for the bodies - let background_transform = Transform::from_translation(backgrounds_res.background_transation); + let background_transform = Transform::from_translation(backgrounds_res.background_transation) + .with_scale(Vec3::new(1.5, 1.5, 1.0)); let star_transform = Transform::from_xyz( rng.gen_range(backgrounds_res.star_position_x_range.clone()), 0.0, @@ -213,6 +224,7 @@ pub fn create_background_system( rotation_speed: rng.gen_range(backgrounds_res.rotation_speed_range.clone()), }) .insert(GameCleanup) + .insert(MainMenuCleanup) .insert(Visibility::default()) .insert(InheritedVisibility::default()) .insert(Name::new("Planet")); @@ -266,6 +278,7 @@ pub fn create_background_system( let mut background_commands = commands.spawn_empty(); background_commands .insert(GameCleanup) + .insert(MainMenuCleanup) .insert(Visibility::default()) .insert(InheritedVisibility::default()) .insert(Name::new("Space Background")) @@ -338,6 +351,7 @@ pub fn create_background_system( ..default() },)) .insert(GameCleanup) + .insert(MainMenuCleanup) .insert(Visibility::default()) .insert(InheritedVisibility::default()) .insert(Name::new("Star")) From 44800961a4f12fdbf2882482c6fa96485e9bb41b Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Tue, 27 Feb 2024 22:17:55 -0600 Subject: [PATCH 07/22] add new button art and hover effect --- src/ui/button.rs | 76 +++++++++++++++++++++++++++++++++++++++------ src/ui/main_menu.rs | 28 ++++++++++++++++- src/ui/mod.rs | 4 +-- 3 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/ui/button.rs b/src/ui/button.rs index 3f221cfa..5037a8de 100644 --- a/src/ui/button.rs +++ b/src/ui/button.rs @@ -1,8 +1,21 @@ use bevy::{ - asset::Handle, - hierarchy::ChildBuilder, - render::texture::Image, - ui::{node_bundles::ButtonBundle, AlignItems, JustifyContent, Style, UiRect, Val}, + asset::{self, AssetServer, Handle}, + ecs::{ + component::Component, + query::{Changed, With}, + system::{Query, Res}, + }, + hierarchy::{BuildChildren, ChildBuilder, Children}, + log::info, + render::{color::Color, texture::Image}, + text::{Font, Text, TextStyle}, + transform::components::Transform, + ui::{ + node_bundles::{ButtonBundle, NodeBundle, TextBundle}, + widget::Button, + AlignItems, BackgroundColor, BorderColor, Interaction, JustifyContent, Style, UiImage, + UiRect, Val, + }, utils::default, }; @@ -11,26 +24,71 @@ const BUTTON_MAX_WIDTH: Val = Val::Px(500.0); const BUTTON_MIN_WIDTH: Val = Val::Px(200.0); const BUTTON_MARGIN: UiRect = UiRect::new(Val::Auto, Val::Auto, Val::Percent(1.0), Val::Percent(1.0)); +const BUTTON_UP_PATH: &str = "texture/menu_button_up.png"; +const BUTTON_DOWN_PATH: &str = "texture/menu_button_down.png"; + +#[derive(Component)] +pub struct ThetawaveUiButtonComponent; pub trait UiChildBuilderExt { - fn spawn_menu_button(&mut self, image: Handle); + fn spawn_menu_button(&mut self, asset_server: &AssetServer, text: String, font: Handle); } impl UiChildBuilderExt for ChildBuilder<'_> { - fn spawn_menu_button(&mut self, image: Handle) { + fn spawn_menu_button(&mut self, asset_server: &AssetServer, text: String, font: Handle) { self.spawn(ButtonBundle { style: Style { max_width: BUTTON_MAX_WIDTH, width: BUTTON_WIDTH, min_width: BUTTON_MIN_WIDTH, - aspect_ratio: Some(132.0 / 32.0), + aspect_ratio: Some(160.0 / 34.0), justify_content: JustifyContent::Center, - align_items: AlignItems::Center, + align_items: AlignItems::FlexStart, margin: BUTTON_MARGIN, + padding: UiRect::top(Val::Percent(2.2)), ..default() }, - image: image.into(), + image: asset_server.load(BUTTON_UP_PATH).into(), ..default() + }) + .insert(ThetawaveUiButtonComponent) + .with_children(|parent| { + parent.spawn( + TextBundle::from_section( + text, + TextStyle { + font: font.clone(), + font_size: 32.0, + color: Color::BLACK, + }, + ) + .with_style(Style { + //margin: UiRect::top(Val::Percent(44.0)), + ..default() + }), + ); }); } } + +pub fn button_system( + mut interaction_query: Query< + (&mut UiImage, &Interaction, &mut Style, &Children), + (Changed, With