//! micro_musicbox provides a convenience wrapper around bevy_kira_audio, handling all the //! setup for the common game audio scenario. This includes channel management, giving you //! control of the audio levels for your music, ambiance, sound effects and UI separately //! from the start. //! //! ## Quickstart //! //! - Implement `SuppliesAudio` for a resource (or use the built-in impl on `AssetServer`) //! - Include the MusixBocPlugin plugin, or the CombinedAudioPlugins plugin group in your app, providing your `SuppliesAudio` impl as the generic parameter //! - Use `MusicBox<T: SuppliesAudio>` as a parameter on a system //! - Call one of the `MusicBox::play_*` methods to play sounds //! //! ```rust //! # use bevy::prelude::*; //! # use micro_musicbox::prelude::*; //! # use micro_musicbox::CombinedAudioPlugins; //! fn main() { //! App::new() //! .add_plugins(CombinedAudioPlugins::<AssetServer>::new()) //! .add_startup_system(|mut music_box: MusicBox<AssetServer>| { //! music_box.play_music("music/bing_bong.mp3"); //! }); //! } //! ``` use std::marker::PhantomData; use bevy::app::{App, CoreStage, Plugin, PluginGroup, PluginGroupBuilder}; use bevy_kira_audio::{AudioApp, AudioPlugin}; use crate::channels::{ AmbianceAudioChannel, MusicAudioChannel, SfxAudioChannel, UiSfxAudioChannel, }; use crate::music_box::MusicBoxState; use crate::utilities::{AudioSettings, SuppliesAudio}; /// The available channels that you can play audio on pub mod channels; pub mod music_box; pub mod utilities; pub mod prelude { pub use bevy_kira_audio::{ AudioChannel, AudioControl, AudioEasing, AudioInstance, AudioSettings as KiraAudioSettings, AudioSource, AudioTween, }; pub use super::channels::*; pub use super::music_box::MusicBox; pub use super::utilities::AudioSettings; } /// A Bevy plugin that sets up all of the audio channels, /// creates the required settings resources, and configures /// syncing volume levels for a `MusicBox` that uses the supplied /// `T` parameter for fetching audio pub struct MusicBoxPlugin<T: SuppliesAudio> { _t: PhantomData<T>, } impl<T: SuppliesAudio> Default for MusicBoxPlugin<T> { fn default() -> Self { Self { _t: PhantomData::default(), } } } impl<T: SuppliesAudio> MusicBoxPlugin<T> { /// Create a new MusicBoxPlugin pub fn new() -> MusicBoxPlugin<T> { Default::default() } } impl<T: SuppliesAudio> Plugin for MusicBoxPlugin<T> { fn build(&self, app: &mut App) { app.add_audio_channel::<MusicAudioChannel>() .add_audio_channel::<AmbianceAudioChannel>() .add_audio_channel::<SfxAudioChannel>() .add_audio_channel::<UiSfxAudioChannel>() .insert_resource(AudioSettings::default()) .insert_resource(MusicBoxState::default()) .add_system_to_stage(CoreStage::Last, utilities::sync_music_volume::<T>); } } /// A Bevy plugin group that adds `bevy_kira_audio` as well as the /// plugin required to be able to use a `MusicBox` pub struct CombinedAudioPlugins<T: SuppliesAudio> { _t: PhantomData<T>, } impl<T: SuppliesAudio> Default for CombinedAudioPlugins<T> { fn default() -> Self { Self { _t: PhantomData::default(), } } } impl<T: SuppliesAudio> CombinedAudioPlugins<T> { pub fn new() -> CombinedAudioPlugins<T> { Default::default() } } impl<T: SuppliesAudio> PluginGroup for CombinedAudioPlugins<T> { fn build(&mut self, group: &mut PluginGroupBuilder) { group.add(AudioPlugin).add(MusicBoxPlugin::<T>::new()); } }