Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into cargo-generate
Browse files Browse the repository at this point in the history
  • Loading branch information
janhohenheim committed Jul 19, 2024
2 parents ff87826 + ed6fe05 commit b298f08
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 85 deletions.
2 changes: 1 addition & 1 deletion docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ By returning `EntityCommands`, you can easily chain multiple widgets together an
Define your assets in an enum so each variant maps to a `Handle`:

```rust
#[derive(PartialEq, Eq, Hash, Reflect)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Reflect)]
pub enum SpriteKey {
Player,
Enemy,
Expand Down
4 changes: 2 additions & 2 deletions src/game/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::time::Duration;

use bevy::prelude::*;

use super::{audio::sfx::Sfx, movement::MovementController};
use super::{audio::sfx::PlaySfx, movement::MovementController};
use crate::AppSet;

pub(super) fn plugin(app: &mut App) {
Expand Down Expand Up @@ -71,7 +71,7 @@ fn trigger_step_sfx(mut commands: Commands, mut step_query: Query<&PlayerAnimati
&& animation.changed()
&& (animation.frame == 2 || animation.frame == 5)
{
commands.trigger(Sfx::Step);
commands.trigger(PlaySfx::RandomStep);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/game/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub(super) fn plugin(app: &mut App) {
app.init_resource::<HandleMap<SoundtrackKey>>();
}

#[derive(PartialEq, Eq, Hash, Reflect)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Reflect)]
pub enum ImageKey {
Ducky,
}
Expand All @@ -40,7 +40,7 @@ impl FromWorld for HandleMap<ImageKey> {
}
}

#[derive(PartialEq, Eq, Hash, Reflect)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Reflect)]
pub enum SfxKey {
ButtonHover,
ButtonPress,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl FromWorld for HandleMap<SfxKey> {
}
}

#[derive(PartialEq, Eq, Hash, Reflect)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Reflect)]
pub enum SoundtrackKey {
Credits,
Gameplay,
Expand Down
19 changes: 1 addition & 18 deletions src/game/audio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,7 @@ pub mod sfx;
pub mod soundtrack;

use bevy::prelude::*;
use sfx::Sfx;

pub fn plugin(app: &mut App) {
app.add_systems(Update, button_interaction_sfx);

app.observe(soundtrack::play_soundtrack);
app.observe(sfx::play_sfx);
}

fn button_interaction_sfx(
mut interactions: Query<&'static Interaction, Changed<Interaction>>,
mut commands: Commands,
) {
for interaction in &mut interactions {
match interaction {
Interaction::Hovered => commands.trigger(Sfx::ButtonHover),
Interaction::Pressed => commands.trigger(Sfx::ButtonPress),
_ => {}
}
}
app.add_plugins((sfx::plugin, soundtrack::plugin));
}
52 changes: 25 additions & 27 deletions src/game/audio/sfx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,38 @@ use rand::seq::SliceRandom;

use crate::game::assets::{HandleMap, SfxKey};

pub(super) fn play_sfx(
trigger: Trigger<Sfx>,
pub(super) fn plugin(app: &mut App) {
app.observe(play_sfx);
}

fn play_sfx(
trigger: Trigger<PlaySfx>,
mut commands: Commands,
sfx_handles: Res<HandleMap<SfxKey>>,
) {
let event = trigger.event();
let source = match event {
Sfx::ButtonHover => &sfx_handles[&SfxKey::ButtonHover],
Sfx::ButtonPress => &sfx_handles[&SfxKey::ButtonPress],
Sfx::Step => random_step(&sfx_handles),
}
.clone_weak();
let settings = PlaybackSettings {
mode: PlaybackMode::Despawn,
..default()
let sfx_key = match trigger.event() {
PlaySfx::Key(key) => *key,
PlaySfx::RandomStep => random_step(),
};
commands.spawn(AudioSourceBundle { source, settings });
commands.spawn(AudioSourceBundle {
source: sfx_handles[&sfx_key].clone_weak(),
settings: PlaybackSettings {
mode: PlaybackMode::Despawn,
..default()
},
});
}

/// Play a single sound effect.
/// Trigger this event to play a single sound effect.
#[derive(Event)]
pub enum Sfx {
ButtonHover,
ButtonPress,
Step,
pub enum PlaySfx {
Key(SfxKey),
RandomStep,
}

fn random_step(sfx_handles: &HandleMap<SfxKey>) -> &Handle<AudioSource> {
[
&sfx_handles[&SfxKey::Step1],
&sfx_handles[&SfxKey::Step2],
&sfx_handles[&SfxKey::Step3],
&sfx_handles[&SfxKey::Step4],
]
.choose(&mut rand::thread_rng())
.unwrap()
fn random_step() -> SfxKey {
[SfxKey::Step1, SfxKey::Step2, SfxKey::Step3, SfxKey::Step4]
.choose(&mut rand::thread_rng())
.copied()
.unwrap()
}
58 changes: 31 additions & 27 deletions src/game/audio/soundtrack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,47 @@ use bevy::{audio::PlaybackMode, prelude::*};

use crate::game::assets::{HandleMap, SoundtrackKey};

pub(super) fn play_soundtrack(
trigger: Trigger<Soundtrack>,
pub(super) fn plugin(app: &mut App) {
app.register_type::<IsSoundtrack>();
app.observe(play_soundtrack);
}

fn play_soundtrack(
trigger: Trigger<PlaySoundtrack>,
mut commands: Commands,
soundtrack_handles: Res<HandleMap<SoundtrackKey>>,
query: Query<Entity, With<SoundtrackMarker>>,
soundtrack_query: Query<Entity, With<IsSoundtrack>>,
) {
let event = trigger.event();
for entity in query.iter() {
commands.entity(entity).despawn();
}

let source = match event {
Soundtrack::Disable => {
return;
}
Soundtrack::Credits => &soundtrack_handles[&SoundtrackKey::Credits],
Soundtrack::Gameplay => &soundtrack_handles[&SoundtrackKey::Gameplay],
for entity in &soundtrack_query {
commands.entity(entity).despawn_recursive();
}
.clone_weak();

let settings = PlaybackSettings {
mode: PlaybackMode::Loop,
..default()
let soundtrack_key = match trigger.event() {
PlaySoundtrack::Key(key) => *key,
PlaySoundtrack::Disable => return,
};
commands.spawn((AudioSourceBundle { source, settings }, SoundtrackMarker));
commands.spawn((
AudioSourceBundle {
source: soundtrack_handles[&soundtrack_key].clone_weak(),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
..default()
},
},
IsSoundtrack,
));
}

/// We mark our soundtrack entity so we can find it later.
#[derive(Component)]
pub(super) struct SoundtrackMarker;

/// Play or disable the soundtrack.
/// Trigger this event to play or disable the soundtrack.
/// Playing a new soundtrack will overwrite the previous one.
/// Soundtracks will loop.
#[derive(Event)]
pub enum Soundtrack {
Credits,
Gameplay,
pub enum PlaySoundtrack {
Key(SoundtrackKey),
Disable,
}

/// Marker component for the soundtrack entity so we can find it later.
#[derive(Component, Reflect)]
#[reflect(Component)]
struct IsSoundtrack;
9 changes: 6 additions & 3 deletions src/screen/credits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
use bevy::prelude::*;

use super::Screen;
use crate::{game::audio::soundtrack::Soundtrack, ui::prelude::*};
use crate::{
game::{assets::SoundtrackKey, audio::soundtrack::PlaySoundtrack},
ui::prelude::*,
};

pub(super) fn plugin(app: &mut App) {
app.add_systems(OnEnter(Screen::Credits), enter_credits);
Expand Down Expand Up @@ -39,11 +42,11 @@ fn enter_credits(mut commands: Commands) {
children.button("Back").insert(CreditsAction::Back);
});

commands.trigger(Soundtrack::Credits);
commands.trigger(PlaySoundtrack::Key(SoundtrackKey::Credits));
}

fn exit_credits(mut commands: Commands) {
commands.trigger(Soundtrack::Disable);
commands.trigger(PlaySoundtrack::Disable);
}

fn handle_credits_action(
Expand Down
8 changes: 5 additions & 3 deletions src/screen/playing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
use bevy::{input::common_conditions::input_just_pressed, prelude::*};

use super::Screen;
use crate::game::{audio::soundtrack::Soundtrack, spawn::level::SpawnLevel};
use crate::game::{
assets::SoundtrackKey, audio::soundtrack::PlaySoundtrack, spawn::level::SpawnLevel,
};

pub(super) fn plugin(app: &mut App) {
app.add_systems(OnEnter(Screen::Playing), enter_playing);
Expand All @@ -18,12 +20,12 @@ pub(super) fn plugin(app: &mut App) {

fn enter_playing(mut commands: Commands) {
commands.trigger(SpawnLevel);
commands.trigger(Soundtrack::Gameplay);
commands.trigger(PlaySoundtrack::Key(SoundtrackKey::Gameplay));
}

fn exit_playing(mut commands: Commands) {
// We could use [`StateScoped`] on the sound playing entites instead.
commands.trigger(Soundtrack::Disable);
commands.trigger(PlaySoundtrack::Disable);
}

fn return_to_title_screen(mut next_screen: ResMut<NextState<Screen>>) {
Expand Down
17 changes: 16 additions & 1 deletion src/ui/interaction.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use bevy::prelude::*;

use crate::game::{assets::SfxKey, audio::sfx::PlaySfx};

pub(super) fn plugin(app: &mut App) {
app.register_type::<InteractionPalette>();
app.add_systems(Update, apply_interaction_palette);
app.add_systems(Update, (apply_interaction_palette, trigger_interaction_sfx));
}

pub type InteractionQuery<'w, 's, T> =
Expand All @@ -29,3 +31,16 @@ fn apply_interaction_palette(
.into();
}
}

fn trigger_interaction_sfx(
mut interactions: Query<&Interaction, Changed<Interaction>>,
mut commands: Commands,
) {
for interaction in &mut interactions {
match interaction {
Interaction::Hovered => commands.trigger(PlaySfx::Key(SfxKey::ButtonHover)),
Interaction::Pressed => commands.trigger(PlaySfx::Key(SfxKey::ButtonPress)),
_ => (),
}
}
}

0 comments on commit b298f08

Please sign in to comment.