Skip to content

Commit

Permalink
Turn on / off background music via SettingsMenu and sync it with the …
Browse files Browse the repository at this point in the history
…UI and the game

- Change the volume by pressing the +1 or -1 buttons and update the text
  • Loading branch information
MadMed677 committed Aug 8, 2022
1 parent bb781bf commit 9475a1c
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 72 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## [0.1.8] - 2022-08-07
### Added
- Add damage to the enemy when the player interacts with them.
- Add an ability to change settings. For now, it's only
music
- Ability to turn on / off music
- Ability to increase / decrease volume
- Ability to go back to the main menu

### Changed
- Move `MainMenuUI` and `DeadMenuUI` into `UI` plugin and add only this plugin in `main.rs`. We may add
additional UI plugins later and it will not affect main file.

## [0.1.7] - 2022-07-24
| Out-of bounce dead | Enemy damage |
| ------------------ | ------------ |
Expand Down
53 changes: 35 additions & 18 deletions src/audio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct Background;
#[derive(PartialEq, Debug)]
enum BackgroundMusicState {
/// Music playing
// Playing,
Playing,

/// Music has been paused
Paused,
Expand All @@ -29,7 +29,7 @@ pub struct AudioState {
bg_handle: Handle<AudioSource>,
bg_state: BackgroundMusicState,

pub volume: f32,
pub volume: i8,
}

impl Plugin for GameAudioPlugin {
Expand All @@ -42,30 +42,47 @@ impl Plugin for GameAudioPlugin {
}
}

fn start_bg_music(background_audio: Res<AudioChannel<Background>>, audio_state: Res<AudioState>) {
match audio_state.bg_state {
// If the song is stopped or never played before we just need to start it
BackgroundMusicState::Stopped => {
background_audio.play_looped(audio_state.bg_handle.clone());
background_audio.set_volume(audio_state.volume);
fn start_bg_music(
background_audio: Res<AudioChannel<Background>>,
mut audio_state: ResMut<AudioState>,
) {
if audio_state.state {
match audio_state.bg_state {
// If the song is stopped or never played before we just need to start it
BackgroundMusicState::Stopped => {
background_audio.play_looped(audio_state.bg_handle.clone());
audio_state.bg_state = BackgroundMusicState::Playing;
}

// We don't need to do anything if the song is already playing
BackgroundMusicState::Playing => {}

// We have to resume the music then
BackgroundMusicState::Paused => {
background_audio.resume();
audio_state.bg_state = BackgroundMusicState::Playing;
}
}

// We don't need to do anything if the song is already playing
// BackgroundMusicState::Playing => {}

// We have to resume the music then
BackgroundMusicState::Paused => {
background_audio.resume();
}
background_audio.set_volume(audio_state.volume as f32 / 10.0);
} else {
background_audio.stop();
}
}

fn stop_bg_music(
background_audio: Res<AudioChannel<Background>>,
mut audio_state: ResMut<AudioState>,
) {
background_audio.pause();
audio_state.bg_state = BackgroundMusicState::Paused;
// If the audio is turned on we just need to pause the music
// Otherwise - stop the music and change the BackgroundMusicState
if audio_state.state {
background_audio.pause();
audio_state.bg_state = BackgroundMusicState::Paused;
} else {
background_audio.stop();
audio_state.bg_state = BackgroundMusicState::Stopped;
}
}

fn load_audio(mut commands: Commands, assets: Res<AssetServer>) {
Expand All @@ -79,6 +96,6 @@ fn load_audio(mut commands: Commands, assets: Res<AssetServer>) {

bg_handle: bgm_handle,
bg_state: BackgroundMusicState::Stopped,
volume: 0.5,
volume: 5,
});
}
4 changes: 1 addition & 3 deletions src/ui/main_menu_ui.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use bevy::prelude::*;
use iyes_loopless::prelude::*;

use crate::{
ApplicationState, ApplicationStateMenu, ExitTheGameEvent, ResumeTheGameEvent,
};
use crate::{ApplicationState, ApplicationStateMenu, ExitTheGameEvent, ResumeTheGameEvent};

use super::components::{
build_classic_button, build_classic_text, HOVERED_BUTTON, NORMAL_BUTTON, PRESSED_BUTTON,
Expand Down
157 changes: 106 additions & 51 deletions src/ui/settings_menu_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl Plugin for SettingsMenuUIPlugin {
.with_system(button_interaction)
.with_system(update_buttons_color)
.with_system(change_music_state)
.with_system(change_music_volume)
.into(),
)
.add_enter_system(
Expand All @@ -28,7 +29,8 @@ impl Plugin for SettingsMenuUIPlugin {
ApplicationState::Menu(ApplicationStateMenu::Settings),
destroy,
)
.add_event::<ChangeMusicStateEvent>();
.add_event::<ChangeMusicStateEvent>()
.add_event::<ChangeMusicVolumeEvent>();
}
}

Expand All @@ -50,7 +52,7 @@ impl Default for MusicState {
#[derive(Debug, Inspectable)]
enum SettingsButtonType {
MusicStatus(MusicState),
MusicVolume(f32),
MusicVolume(i8),
BackToMenu,
}

Expand All @@ -60,13 +62,24 @@ pub struct SettingsButton(SettingsButtonType);
#[derive(Component)]
struct Active;

#[derive(Debug, Inspectable, Component)]
enum SettingsTextType {
Volume,
}

/// Event which triggers when the music state
/// should be changed
/// Accepts Entity on which state user select state
struct ChangeMusicStateEvent(Entity);

/// Event which triggers when the music volume
/// should be changed
/// Accepts the diff on which we should change the volume
struct ChangeMusicVolumeEvent(i8);

#[allow(clippy::type_complexity)]
fn button_interaction(
mut commands: Commands,
mut interaction_query: Query<
(
Entity,
Expand All @@ -78,14 +91,23 @@ fn button_interaction(
(Changed<Interaction>, With<Button>),
>,
mut change_music_state_event: EventWriter<ChangeMusicStateEvent>,
mut change_music_volume_event: EventWriter<ChangeMusicVolumeEvent>,
) {
for (entity, interaction, mut color, settings_button, active) in interaction_query.iter_mut() {
match *interaction {
Interaction::Clicked => {
if let SettingsButtonType::MusicStatus(_) = &settings_button.0 {
Interaction::Clicked => match &settings_button.0 {
SettingsButtonType::MusicStatus(_) => {
change_music_state_event.send(ChangeMusicStateEvent(entity));
}
}
SettingsButtonType::MusicVolume(volume) => {
change_music_volume_event.send(ChangeMusicVolumeEvent(*volume));
}
SettingsButtonType::BackToMenu => {
commands.insert_resource(NextState(ApplicationState::Menu(
ApplicationStateMenu::Main,
)));
}
},
Interaction::Hovered => {
if active.is_none() {
*color = UiColor(HOVERED_BUTTON);
Expand Down Expand Up @@ -119,10 +141,31 @@ fn update_buttons_color(
}
}

fn change_music_volume(
mut change_music_volume_event: EventReader<ChangeMusicVolumeEvent>,
mut audio_state: ResMut<AudioState>,
mut music_text_query: Query<(&mut Text, &SettingsTextType), With<SettingsTextType>>,
) {
for event in change_music_volume_event.iter() {
audio_state.volume += event.0;

for (mut music_text_text, _) in music_text_query.iter_mut() {
// We should check the Volume text type when we will have more than
// one enum value
// if let SettingsTextType::Volume = &music_text_type {
// }

music_text_text.sections[0].value = audio_state.volume.to_string();
}
}
}

fn change_music_state(
mut commands: Commands,
music_buttons_query: Query<(Entity, &SettingsButton), With<SettingsButton>>,
mut change_music_state_event: EventReader<ChangeMusicStateEvent>,
active_button_query: Query<&SettingsButton>,
mut audio_state: ResMut<AudioState>,
) {
for event in change_music_state_event.iter() {
for (music_button_entity, music_button_settings) in music_buttons_query.iter() {
Expand All @@ -134,6 +177,20 @@ fn change_music_state(
let active_button = event.0;

commands.entity(active_button).insert(Active);

if let Ok(active_button_settings) = active_button_query.get(active_button) {
if let SettingsButtonType::MusicStatus(music_state) = &active_button_settings.0 {
// Turn the music on / off
match music_state {
MusicState::On => {
audio_state.state = true;
}
MusicState::Off => {
audio_state.state = false;
}
}
}
}
}
}

Expand Down Expand Up @@ -245,12 +302,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, audio_state: Re
on_button.insert(Active);
}

parent.spawn_bundle(build_classic_text(
(audio_state.volume * 100.0).to_string().as_str(),
&asset_server,
None,
));

let mut off_button =
parent.spawn_bundle(build_classic_button());

Expand All @@ -270,6 +321,50 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, audio_state: Re
off_button.insert(Active);
}
});
})
.with_children(|parent| {
parent
.spawn_bundle(NodeBundle {
style: Style {
size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
},
color: Color::NONE.into(),
..Default::default()
})
.with_children(|parent| {
parent
.spawn_bundle(build_classic_button())
.insert(SettingsButton(SettingsButtonType::MusicVolume(-1)))
.with_children(|parent| {
parent.spawn_bundle(build_classic_text(
"-1",
&asset_server,
None,
));
});

parent
.spawn_bundle(build_classic_text(
audio_state.volume.to_string().as_str(),
&asset_server,
None,
))
.insert(SettingsTextType::Volume);

parent
.spawn_bundle(build_classic_button())
.insert(SettingsButton(SettingsButtonType::MusicVolume(1)))
.with_children(|parent| {
parent.spawn_bundle(build_classic_text(
"+1",
&asset_server,
None,
));
});
});
});
})
.with_children(|parent| {
Expand Down Expand Up @@ -298,46 +393,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, audio_state: Re
});
});
});

// parent
// .spawn_bundle(NodeBundle {
// style: Style {
// size: Size::new(Val::Percent(100.0), Val::Percent(70.0)),
// flex_direction: FlexDirection::ColumnReverse,
// border: Rect::all(Val::Px(5.0)),
// ..Default::default()
// },
// color: Color::NONE.into(),
// ..Default::default()
// })
// .with_children(|parent| {
// parent
// .spawn_bundle(build_classic_button())
// .insert(SettingsButton(SettingsButtonType::MusicStatus(
// MusicState::On,
// )))
// .with_children(|parent| {
// parent.spawn_bundle(build_classic_text("On", &asset_server, None));
// });
// })
// .with_children(|parent| {
// parent
// .spawn_bundle(build_classic_button())
// .insert(SettingsButton(SettingsButtonType::MusicStatus(
// MusicState::Off,
// )))
// .with_children(|parent| {
// parent.spawn_bundle(build_classic_text("Off", &asset_server, None));
// });
// })
// .with_children(|parent| {
// parent
// .spawn_bundle(build_classic_button())
// .insert(SettingsButton(SettingsButtonType::BackToMenu))
// .with_children(|parent| {
// parent.spawn_bundle(build_classic_text("Back", &asset_server, None));
// });
// });
})
.insert(SettingsMenuUI);
}
Expand Down

0 comments on commit 9475a1c

Please sign in to comment.