99//! # use rusty_engine::prelude::*;
1010//! #
1111//! # fn main() {
12- //! # let mut engine = Game::new();
12+ //! # let mut game = Game::new();
1313//! // Inside your logic function...
14- //! engine .audio_manager.play_sfx("my_sound_effect.mp3", 1.0);
15- //! # engine .run(());
14+ //! game .audio_manager.play_sfx("my_sound_effect.mp3", 1.0);
15+ //! # game .run(());
1616//! # }
1717//! ```
1818//!
2222//! # use rusty_engine::prelude::*;
2323//! #
2424//! # fn main() {
25- //! # let mut engine = Game::new();
25+ //! # let mut game = Game::new();
2626//! // Inside your logic function...
27- //! engine .audio_manager.play_music("my_game/spooky_loop.ogg", 1.0);
28- //! # engine .run(());
27+ //! game .audio_manager.play_music("my_game/spooky_loop.ogg", 1.0);
28+ //! # game .run(());
2929//! # }
3030//! ```
3131//!
3636//! use rusty_engine::prelude::*;
3737//!
3838//! # fn main() {
39- //! # let mut engine = Game::new();
39+ //! # let mut game = Game::new();
4040//! // Inside your logic function...
41- //! engine .audio_manager.play_sfx(SfxPreset::Confirmation1, 1.0);
42- //! engine .audio_manager.play_music(MusicPreset::Classy8Bit, 1.0);
43- //! # engine .run(());
41+ //! game .audio_manager.play_sfx(SfxPreset::Confirmation1, 1.0);
42+ //! game .audio_manager.play_music(MusicPreset::Classy8Bit, 1.0);
43+ //! # game .run(());
4444//! # }
4545//! ```
4646//!
4747
4848use crate :: prelude:: Engine ;
49- use bevy:: prelude:: * ;
50- use bevy_kira_audio:: { Audio , AudioChannel } ;
51- use std:: array:: IntoIter ;
49+ use bevy:: { audio:: AudioSink , prelude:: * } ;
50+ use std:: { array:: IntoIter , fmt:: Debug } ;
5251
5352#[ derive( Default ) ]
5453#[ doc( hidden) ]
@@ -64,14 +63,24 @@ impl Plugin for AudioManagerPlugin {
6463/// You will interact with a [`AudioManager`] for all audio needs in Rusty Engine. It is exposed
6564/// through the [`Engine`](crate::prelude::Engine) struct provided to your logic function
6665/// each frame as the [`audio_manager`](crate::prelude::Engine::audio_manager) field.
67- #[ derive( Debug , Default ) ]
66+ #[ derive( Default ) ]
6867pub struct AudioManager {
6968 sfx_queue : Vec < ( String , f32 ) > ,
7069 music_queue : Vec < Option < ( String , f32 ) > > ,
71- playing : AudioChannel ,
70+ playing : Option < Handle < AudioSink > > ,
7271 music_playing : bool ,
7372}
7473
74+ impl Debug for AudioManager {
75+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
76+ f. debug_struct ( "AudioManager" )
77+ . field ( "sfx_queue" , & self . sfx_queue )
78+ . field ( "music_queue" , & self . music_queue )
79+ . field ( "music_playing" , & self . music_playing )
80+ . finish ( )
81+ }
82+ }
83+
7584impl AudioManager {
7685 /// Play a sound effect. `volume` ranges from `0.0` to `1.0`. `sfx` can be an [`SfxPreset`] or a
7786 /// string containing the relative path/filename of a sound file within the `assets/audio`
@@ -107,7 +116,7 @@ impl AudioManager {
107116/// `sfx` example by cloning the `rusty_engine` repository and running the following command:
108117///
109118/// ```text
110- /// cargo run --release --example sfx
119+ /// cargo run --release --example sfx_sampler
111120/// ```
112121pub enum SfxPreset {
113122 Click ,
@@ -185,7 +194,7 @@ impl From<SfxPreset> for String {
185194/// by cloning the `rusty_engine` repository and running the following command:
186195///
187196/// ```text
188- /// cargo run --release --example music
197+ /// cargo run --release --example music_sampler
189198/// ```
190199#[ derive( Copy , Clone , Debug ) ]
191200pub enum MusicPreset {
@@ -208,9 +217,9 @@ impl MusicPreset {
208217impl From < MusicPreset > for String {
209218 fn from ( music_preset : MusicPreset ) -> String {
210219 match music_preset {
211- MusicPreset :: Classy8Bit => "music/Classy 8-Bit.oga " . into ( ) ,
212- MusicPreset :: MysteriousMagic => "music/Mysterious Magic.oga " . into ( ) ,
213- MusicPreset :: WhimsicalPopsicle => "music/Whimsical Popsicle.oga " . into ( ) ,
220+ MusicPreset :: Classy8Bit => "music/Classy 8-Bit.ogg " . into ( ) ,
221+ MusicPreset :: MysteriousMagic => "music/Mysterious Magic.ogg " . into ( ) ,
222+ MusicPreset :: WhimsicalPopsicle => "music/Whimsical Popsicle.ogg " . into ( ) ,
214223 }
215224 }
216225}
@@ -220,30 +229,40 @@ impl From<MusicPreset> for String {
220229pub fn queue_managed_audio_system (
221230 asset_server : Res < AssetServer > ,
222231 audio : Res < Audio > ,
232+ audio_sinks : Res < Assets < AudioSink > > ,
223233 mut game_state : ResMut < Engine > ,
224234) {
225235 for ( sfx, volume) in game_state. audio_manager . sfx_queue . drain ( ..) {
226236 let sfx_path = format ! ( "audio/{}" , sfx) ;
227237 let sfx_handle = asset_server. load ( sfx_path. as_str ( ) ) ;
228- // To be able to set the volume of a sound effect, we need the channel it is being played
229- // in. We'll start by naively creating a new channel for every single sound effect. If this
230- // ends up being a performance or correctness problem, we'll need to circle back and do
231- // something more sophisticated (like keep a set number of channels around at different
232- // volumes).
233- let new_sfx_channel = AudioChannel :: new ( sfx_path) ;
234- audio. set_volume_in_channel ( volume, & new_sfx_channel) ;
235- audio. play_in_channel ( sfx_handle, & new_sfx_channel) ;
238+ audio. play_with_settings (
239+ sfx_handle,
240+ PlaybackSettings {
241+ volume,
242+ ..Default :: default ( )
243+ } ,
244+ ) ;
236245 }
237- let mut playing_music = game_state. audio_manager . playing . clone ( ) ;
238- for item in game_state. audio_manager . music_queue . drain ( ..) {
239- audio. stop_channel ( & playing_music) ;
246+ for item in game_state. audio_manager . music_queue . drain ( ..) . last ( ) {
247+ // stop any music currently playing
248+ if let Some ( sink_handle) = & game_state. audio_manager . playing {
249+ if let Some ( sink) = audio_sinks. get ( sink_handle) {
250+ sink. stop ( ) ;
251+ }
252+ }
253+ // start the new music...if we have some
240254 if let Some ( ( music, volume) ) = item {
241255 let music_path = format ! ( "audio/{}" , music) ;
242256 let music_handle = asset_server. load ( music_path. as_str ( ) ) ;
243- playing_music = AudioChannel :: new ( music_path) ;
244- audio. set_volume_in_channel ( volume, & playing_music) ;
245- audio. play_looped_in_channel ( music_handle, & playing_music) ;
257+ let sink_handle = audio_sinks. get_handle ( audio. play_with_settings (
258+ music_handle,
259+ PlaybackSettings {
260+ repeat : true ,
261+ volume,
262+ ..Default :: default ( )
263+ } ,
264+ ) ) ;
265+ game_state. audio_manager . playing = Some ( sink_handle) ;
246266 }
247267 }
248- game_state. audio_manager . playing = playing_music;
249268}
0 commit comments