diff --git a/Cargo.lock b/Cargo.lock index 2b4624d..6f649bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1664,6 +1664,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "claxon" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688" + [[package]] name = "codespan-reporting" version = "0.12.0" @@ -3792,6 +3798,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" dependencies = [ + "claxon", "cpal", "hound", "lewton", diff --git a/Cargo.toml b/Cargo.toml index 2a57794..0f654ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ bevy = { version = "0.17.2", default-features = false, features = [ "bevy_state", "bevy_audio", "multi_threaded", + "flac", "png", "std", "vorbis", diff --git a/assets/soundtrack/space.flac b/assets/soundtrack/space.flac new file mode 100644 index 0000000..6341773 Binary files /dev/null and b/assets/soundtrack/space.flac differ diff --git a/assets/soundtrack/the-last-parsec.ogg b/assets/soundtrack/the-last-parsec.ogg deleted file mode 100644 index 24eb898..0000000 Binary files a/assets/soundtrack/the-last-parsec.ogg and /dev/null differ diff --git a/src/audio/mod.rs b/src/audio/mod.rs index 466e22d..c6fe9b5 100644 --- a/src/audio/mod.rs +++ b/src/audio/mod.rs @@ -8,7 +8,7 @@ pub(super) fn plugin(app: &mut App) { app.init_resource::(); app.add_observer(on_play_soundtrack_event); app.add_observer(on_play_sfx_event); - app.add_systems(Update, fade_in); + app.add_systems(Update, (fade_in, fade_out)); } #[derive(Resource)] @@ -48,6 +48,7 @@ struct SoundtrackPlayer; pub struct Soundtracks { pub main_theme: Handle, pub battle_theme: Handle, + pub end_theme: Handle, } impl FromWorld for Soundtracks { @@ -56,17 +57,20 @@ impl FromWorld for Soundtracks { let soundtracks = Soundtracks { main_theme: asset_server.load("soundtrack/spacetheme.ogg"), battle_theme: asset_server.load("soundtrack/through-space.ogg"), + end_theme: asset_server.load("soundtrack/space.flac"), }; Self { main_theme: soundtracks.main_theme, battle_theme: soundtracks.battle_theme, + end_theme: soundtracks.end_theme, } } } pub enum Soundtrack { - MainTheme, - BattleTheme, + Main, + Battle, + End, } #[derive(Event)] @@ -84,29 +88,36 @@ fn on_play_soundtrack_event( >, ) { let track_handle = match soundtrack_event.soundtrack { - Soundtrack::MainTheme => soundtracks.main_theme.clone(), - Soundtrack::BattleTheme => soundtracks.battle_theme.clone(), + Soundtrack::Main => soundtracks.main_theme.clone(), + Soundtrack::Battle => soundtracks.battle_theme.clone(), + Soundtrack::End => soundtracks.end_theme.clone(), }; + let mut is_already_playing = false; for audio_player_entity in audio_player.iter_mut() { if audio_player_entity.1.0 == track_handle { - return; + is_already_playing = true; + } else { + commands + .entity(audio_player_entity.0) + .insert(FadeOut { duration: 0.5 }); } - commands.entity(audio_player_entity.0).despawn(); } - commands.spawn(( - SoundtrackPlayer, - AudioPlayer(track_handle.clone()), - PlaybackSettings { - mode: PlaybackMode::Loop, - volume: Volume::Linear(0.0), - ..default() - }, - FadeIn { duration: 4.0 }, - Transform::default(), - GlobalTransform::default(), - )); + if !is_already_playing { + commands.spawn(( + SoundtrackPlayer, + AudioPlayer(track_handle.clone()), + PlaybackSettings { + mode: PlaybackMode::Loop, + volume: Volume::Linear(0.0), + ..default() + }, + FadeIn { duration: 4.0 }, + Transform::default(), + GlobalTransform::default(), + )); + } } fn on_play_sfx_event(sfx_event: On, mut commands: Commands, sfx: Res) { @@ -148,3 +159,25 @@ fn fade_in( } } } + +#[derive(Component)] +struct FadeOut { + duration: f32, +} + +fn fade_out( + mut commands: Commands, + mut audio_sink: Query<(&FadeOut, &mut AudioSink, Entity)>, + time: Res