Skip to content

Commit

Permalink
Merge pull request #163 from cdsupina/ui-buttons
Browse files Browse the repository at this point in the history
New Main Menu with 3D Backgrounds and Selectable Buttons
  • Loading branch information
varoonp123 authored Mar 6, 2024
2 parents 5aaf769 + c8c5d98 commit daa7018
Show file tree
Hide file tree
Showing 19 changed files with 711 additions and 237 deletions.
27 changes: 27 additions & 0 deletions assets/game_audio_assets.assets.ron
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,31 @@
"sounds.objective_completed": File (
path: "sounds/objective_completed.wav",
),
"sounds.button_select_1": File (
path: "sounds/button_select_1.wav",
),
"sounds.button_select_2": File (
path: "sounds/button_select_2.wav",
),
"sounds.button_select_3": File (
path: "sounds/button_select_3.wav",
),
"sounds.button_select_4": File (
path: "sounds/button_select_4.wav",
),
"sounds.button_select_5": File (
path: "sounds/button_select_5.wav",
),
"sounds.button_release_1": File (
path: "sounds/button_release_1.wav",
),
"sounds.button_release_2": File (
path: "sounds/button_release_2.wav",
),
"sounds.button_release_3": File (
path: "sounds/button_release_3.wav",
),
"sounds.button_confirm": File (
path: "sounds/button_confirm.wav",
),
})
16 changes: 16 additions & 0 deletions assets/ui_assets.assets.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
({
"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"),
"thetawave_menu_button.layout": TextureAtlasLayout (
tile_size_x: 160.,
tile_size_y: 34.,
columns: 1,
rows: 2,
),
"thetawave_menu_button.image": File( path: "texture/menu_button_spritesheet.png"),
})
3 changes: 3 additions & 0 deletions crates/thetawave_interface/src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub enum SoundEffectType {
BulletBounce,
MegablastAbility,
ObjectiveCompleted,
ButtonSelect,
ButtonRelease,
ButtonConfirm,
}

/// Subtype of sound effect for collisions
Expand Down
2 changes: 2 additions & 0 deletions crates/thetawave_interface/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub enum MenuAction {
ExitPauseMenu,
PauseGame,
ToggleTutorial,
NavigateUp,
NavigateDown,
}

/// Player actions during the main game/while fighting mobs. Many of these can be simultaneously
Expand Down
4 changes: 4 additions & 0 deletions src/animation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<AnimationCompletedEvent>();
Expand Down
38 changes: 38 additions & 0 deletions src/assets/audio.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
use bevy_kira_audio::AudioSource;
use rand::Rng;
use thetawave_interface::audio::{BGMusicType, CollisionSoundType, SoundEffectType};

#[derive(AssetCollection, Resource)]
Expand Down Expand Up @@ -47,6 +48,24 @@ pub struct GameAudioAssets {
pub megablast_ability: Handle<AudioSource>,
#[asset(key = "sounds.objective_completed")]
pub objective_completed: Handle<AudioSource>,
#[asset(key = "sounds.button_select_1")]
pub button_select_1: Handle<AudioSource>,
#[asset(key = "sounds.button_select_2")]
pub button_select_2: Handle<AudioSource>,
#[asset(key = "sounds.button_select_3")]
pub button_select_3: Handle<AudioSource>,
#[asset(key = "sounds.button_select_4")]
pub button_select_4: Handle<AudioSource>,
#[asset(key = "sounds.button_select_5")]
pub button_select_5: Handle<AudioSource>,
#[asset(key = "sounds.button_release_1")]
pub button_release_1: Handle<AudioSource>,
#[asset(key = "sounds.button_release_2")]
pub button_release_2: Handle<AudioSource>,
#[asset(key = "sounds.button_release_3")]
pub button_release_3: Handle<AudioSource>,
#[asset(key = "sounds.button_confirm")]
pub button_confirm: Handle<AudioSource>,
}

impl GameAudioAssets {
Expand Down Expand Up @@ -80,6 +99,25 @@ impl GameAudioAssets {
SoundEffectType::BulletBounce => self.bullet_bounce.clone(),
SoundEffectType::MegablastAbility => self.megablast_ability.clone(),
SoundEffectType::ObjectiveCompleted => self.objective_completed.clone(),
SoundEffectType::ButtonRelease => {
let idx: u8 = rand::thread_rng().gen_range(1..=3);
match idx {
1 => self.button_release_1.clone(),
2 => self.button_release_2.clone(),
_ => self.button_release_3.clone(),
}
}
SoundEffectType::ButtonSelect => {
let idx: u8 = rand::thread_rng().gen_range(1..=5);
match idx {
1 => self.button_select_1.clone(),
2 => self.button_select_2.clone(),
3 => self.button_select_3.clone(),
4 => self.button_select_4.clone(),
_ => self.button_select_5.clone(),
}
}
SoundEffectType::ButtonConfirm => self.button_confirm.clone(),
}
}
}
5 changes: 4 additions & 1 deletion src/assets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*,
};
17 changes: 17 additions & 0 deletions src/assets/ui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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<TextureAtlasLayout>,
#[asset(key = "thetawave_logo.image")]
pub thetawave_logo_image: Handle<Image>,
#[asset(key = "thetawave_menu_button.layout")]
pub thetawave_menu_button_layout: Handle<TextureAtlasLayout>,
#[asset(key = "thetawave_menu_button.image")]
pub thetawave_menu_button_image: Handle<Image>,
}
4 changes: 2 additions & 2 deletions src/audio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ pub fn set_audio_volume_system(
menu_audio_channel: Res<AudioChannel<MenuAudioChannel>>,
effects_audio_channel: Res<AudioChannel<SoundEffectsAudioChannel>>,
) {
background_audio_channel.set_volume(0.70);
background_audio_channel.set_volume(0.20);
menu_audio_channel.set_volume(0.05);
effects_audio_channel.set_volume(0.60);
effects_audio_channel.set_volume(0.80);
}

fn play_sound_effect_system(
Expand Down
18 changes: 16 additions & 2 deletions src/background/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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"));
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -338,6 +351,7 @@ pub fn create_background_system(
..default()
},))
.insert(GameCleanup)
.insert(MainMenuCleanup)
.insert(Visibility::default())
.insert(InheritedVisibility::default())
.insert(Name::new("Star"))
Expand Down
8 changes: 7 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ impl PluginGroup for ThetawaveGamePlugins {

#[cfg(test)]
mod test {
use crate::animation::AnimationPlugin;
use crate::audio::ThetawaveAudioPlugin;
use crate::background::BackgroundPlugin;
use crate::{build_app, options, ui, ThetawaveGamePlugins};
use bevy::app::{App, PluginGroup};
use bevy::asset::AssetPlugin;
Expand Down Expand Up @@ -268,7 +270,11 @@ mod test {
// Ideally audio is mostly handled via `thetawave_interface::audio` and events, so that
// we really only skip testing 1 match statement and external audio deps.
.disable::<ThetawaveAudioPlugin>()
.disable::<AudioPlugin>();
.disable::<AudioPlugin>()
// The background plugin & animation plugins require the render pipeline, which I dont
// not want in CI.
.disable::<AnimationPlugin>()
.disable::<BackgroundPlugin>();

let mut app = build_app(base_plugins, game_plugins);
app.add_event::<ChangeBackgroundMusicEvent>()
Expand Down
2 changes: 1 addition & 1 deletion src/options/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl From<DisplayConfig> 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 {
Expand Down
7 changes: 7 additions & 0 deletions src/options/input.ron
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@
(Reset, KeyR),
(ExitPauseMenu, Escape),
(PauseGame, Escape),
(NavigateUp, KeyW),
(NavigateDown, KeyS),
(NavigateUp, ArrowUp),
(NavigateDown, ArrowDown),
],
menu_gamepad: [
(ChangeCharacterGamepad, DPadLeft),
(ChangeCharacterGamepad, DPadRight),
(ToggleTutorial, DPadUp),
(ToggleTutorial, DPadDown),
(NavigateUp, DPadUp),
(NavigateDown, DPadDown),
(JoinGamepad, South),
(Back, East),
(Confirm, Start),
(Confirm, South),
(Reset, East),
(ExitPauseMenu, Start),
(PauseGame, Start),
Expand Down
21 changes: 0 additions & 21 deletions src/states/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,6 @@ pub fn start_game_system(
}
}

// Start the game by entering the Game state
pub fn start_instructions_system(
menu_input_query: Query<&ActionState<MenuAction>, With<MenuExplorer>>,
mut next_app_state: ResMut<NextState<AppStates>>,
mut sound_effect_pub: EventWriter<PlaySoundEffectEvent>,
) {
// read menu input action
if let Ok(action_state) = menu_input_query.get_single() {
// if input read enter the game state
if action_state.just_released(&MenuAction::Confirm) {
// set the state to game
next_app_state.set(AppStates::Instructions);

// play sound effect
sound_effect_pub.send(PlaySoundEffectEvent {
sound_effect_type: SoundEffectType::MenuInputSuccess,
});
}
}
}

pub fn start_character_selection_system(
menu_input_query: Query<&ActionState<MenuAction>, With<MenuExplorer>>,
mut next_app_state: ResMut<NextState<AppStates>>,
Expand Down
10 changes: 4 additions & 6 deletions src/states/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -60,13 +61,15 @@ impl Plugin for StatesPlugin {
.with_dynamic_assets_file::<StandardDynamicAssetCollection>(
"game_audio_assets.assets.ron",
)
.with_dynamic_assets_file::<StandardDynamicAssetCollection>("ui_assets.assets.ron")
.load_collection::<PlayerAssets>()
.load_collection::<ProjectileAssets>()
.load_collection::<MobAssets>()
.load_collection::<ItemAssets>()
.load_collection::<ConsumableAssets>()
.load_collection::<EffectAssets>()
.load_collection::<GameAudioAssets>(),
.load_collection::<GameAudioAssets>()
.load_collection::<UiAssets>(),
);

app.edit_schedule(OnEnter(AppStates::Game), |schedule| {
Expand Down Expand Up @@ -109,11 +112,6 @@ impl Plugin for StatesPlugin {
.run_if(in_state(GameStates::Playing)),
);

app.add_systems(
Update,
start_instructions_system.run_if(in_state(AppStates::MainMenu)),
);

app.add_systems(
Update,
start_character_selection_system.run_if(in_state(AppStates::Instructions)),
Expand Down
Loading

0 comments on commit daa7018

Please sign in to comment.