Skip to content
Snippets Groups Projects
README.md 5.98 KiB
Newer Older
Louis's avatar
Louis committed
# Micro MusicBox
Louis's avatar
Louis committed

Play some tunes

Louis's avatar
Louis committed
[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue?style=for-the-badge)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)
[![Crates.io](https://img.shields.io/crates/v/micro_musicbox?style=for-the-badge)](https://crates.io/crates/micro_musicbox)
Louis's avatar
Louis committed
[![docs.rs](https://img.shields.io/docsrs/micro_musicbox?style=for-the-badge)](https://docs.rs/micro_musicbox)
Louis's avatar
Louis committed

Louis's avatar
Louis committed
## What?

Louis's avatar
Louis committed
This library 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.
Louis's avatar
Louis committed

Louis's avatar
Louis committed
### Channel Types
Louis's avatar
Louis committed

Louis's avatar
Louis committed
Musicbox is configured with 4 channels, which a re split into two types:
Louis's avatar
Louis committed

Louis's avatar
Louis committed
- Main channels; Play a single looped audio track. Starting another track on this channel will stop the currently active one. Supports cross-fade between the current track and the next track. This includes the "Music" and "Ambiance" channels
- Background Channels; Plays any number of one-shot sounds. The sounds will not interfere with each other or the main channels. This includes the "SFX" and "UI SFX" channels

### Volume

Volume is calculated by multiplying a given channel's volume setting by the master volume setting.
This means you can let players adjust either the overall game volume, or each of the three types
individually. The 4 channels are assigned as such:

- "music" -> music volume * master volume
- "ambiance" & "sfx" -> sfx volume * master volume
- "ui sfx" -> ui volume * master volume

There are two types of channel: Singleton "main" channels, and multi-sound channels. Audio
played on a main channel will loop until stopped, and will replace any currently playing audio
on that same channel. multi-sound channels work exactly as they, well, sound - play one-off sounds
without worrying about coordinating them with other sources.

Main channels also expose a cross-fade feature - either a basic cross-fade, in which the same
audio tween is applied to the outgoing and incoming music tracks, or an in-out fade where the two
tracks can have independent tweens.
Louis's avatar
Louis committed

## How?

### Quickstart

Louis's avatar
Louis committed
- 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
Louis's avatar
Louis committed
- Use `MusicBox<T: SuppliesAudio>` as a parameter on a system
- Call one of the `MusicBox::play_*` methods to play sounds

Louis's avatar
Louis committed
```rust
Louis's avatar
Louis committed
fn main() {
    App::new()
Louis's avatar
Louis committed
        .add_plugins(CombinedAudioPlugins::<AssetServer>::new())
Louis's avatar
Louis committed
        .add_startup_system(|mut music_box: MusicBox<AssetServer>| {
            music_box.play_music("music/bing_bong.mp3");
        });
}
```

### In-Depth

There is a plugin that just provides the layering on top of bevy_kira_audio if you are already integrating with it,
and a plugin group that will setup and configure bevy_kira_audio for you if not. Some bevy_ira_audio types are
re-exported, so you can depend solely on micro_bevy_musicbox if you don't have any advanced needs.

```rust
use micro_bevy_musicbox::{CombinedAudioPlugins, MusicBoxPlugin};

// Either
fn main() {
    App::new()
        .add_plugin(MusicBoxPlugin);
}

// Or
fn main() {
    App::new()
        .add_plugins(CombinedAudioPlugins);
}
```

In order to use the the MusicBox type, you will need to implement the `SuppliesAudio` trait on a resource.
This resource will need to be able to retrieve the requested audio track by name, although the specifics of
what that name represents will depend on how you implement the trait.

Out of the box, there is a `SuppliesAudio` impl for `AssetServer`, allowing you to use resource paths. It is,
however, recommended that you create your own impl for your own resource type.

```rust
/// An example storage resource that allows assets to be retrieved by name,
/// rather than by file path
pub struct AssetHandles {
    // ...Other types...
    pub sounds: HashMap<String, Handle<AudioSource>>,
}

impl SuppliesAudio for AssetHandles {
	fn get_audio_track<T: ToString>(&self, name: T) -> Option<Handle<AudioSource>> {
		self.sounds.get(&name.to_string()).map(Handle::clone_weak)
	}
}
```

Finally, you need to use the `MusicBox` type as a SystemParam, alongside your `SuppliesAudio` impl.
There is no binding of between MusicBox and SuppliesAudio, so you can use different impls in different
systems as you please, as long as the `SuppliesAudio` resource has been added to your world

```rust
/// A simple event that causes a sound effect to be played.
/// N.B. In a real game, you probably just want to directly play a sound without events
pub struct PlaySoundEvent {
    pub sound: String,
}

// ...Register your event to your app...

/// A system that reads PlaySoundEvent events and plays the sound effect, using the
/// previously created `AssetHandles` resource as a supplier
pub fn play_sounds(
    mut events: EventReader<PlaySoundEvent>,
    music_box: MusicBox<AssetHandles>,
) {
    for PlaySoundEvent { sound } in events.iter() {
        music_box.play_effect_once(sound);
    }
}
Louis's avatar
Louis committed
```

## Asset Licenses

The examples in this repository use assets available under the following licenses:

- The-Great-Madeja.mp3 by [Rolemusic](http://rolemusic.sawsquarenoise.com/) is licensed under a [CC-BY-4.0 Attribution License](https://creativecommons.org/licenses/by/4.0/).
- The-White-Kitty.mp3 by [Rolemusic](http://rolemusic.sawsquarenoise.com/) is licensed under a [CC-BY-4.0 Attribution License](https://creativecommons.org/licenses/by/4.0/).
- KenneyBlocks.ttf by [Kenney](https://www.kenney.nl) is licensed under a [CC-0 Public Domain License](http://creativecommons.org/publicdomain/zero/1.0/) 
Louis's avatar
Louis committed

## Compatibility

| musicbox version | bevy version | bka version |
|------------------|--------------|-------------|
Louis's avatar
Louis committed
| 0.6              | 0.10         | 0.15        |
Louis's avatar
Louis committed
| 0.5              | 0.9          | 0.13        |
| 0.4              | 0.8.0        | 0.12        |