Skip to content
Snippets Groups Projects
kitchen_sink.rs 3.71 KiB
Newer Older
Louis's avatar
Louis committed
// This example shows off a number of the features that micro_musicbox provides:
// - Basic music player
// - Channel based audio volume mixing w/ master volume
// - Cross fade audio

use std::time::Duration;

use bevy::prelude::*;
Louis's avatar
Louis committed
use bevy::window::WindowResolution;
Louis's avatar
Louis committed
use micro_musicbox::prelude::*;
use micro_musicbox::CombinedAudioPlugins;

use crate::utilities::{AppState, DetailsMarker, TextMarker};

mod utilities;

pub fn main() {
	App::new()
		.add_plugin(utilities::SetupPlugin) // Loads resources
Louis's avatar
Louis committed
		.add_plugins(DefaultPlugins.set(WindowPlugin {
			primary_window: Some(Window {
				resolution: WindowResolution::new(800.0, 600.0),
				title: String::from("Kitchen Sink Example"),
				..Default::default()
			}),
			..Default::default()
		}))		.add_plugins(CombinedAudioPlugins::<AssetServer>::new())
		.add_system(
			setup_audio.in_schedule(OnEnter(AppState::Running))
		)
		.add_system(
			set_instructions.in_schedule(OnEnter(AppState::Running))
		)
		.add_system(cross_fade_tracks.run_if(resource_exists::<MusicState>()))
Louis's avatar
Louis committed
		.run();
}

/// A resource that we'll use to keep track of which track is currently the active one, for fading
/// in and out
Louis's avatar
Louis committed
#[derive(Resource)]
Louis's avatar
Louis committed
pub struct MusicState {
	pub playing_first: bool,
}

Louis's avatar
Louis committed
// pub fn has_music_state(state: Option<Res<MusicState>>) -> ShouldRun {
// 	state.is_some().into()
// }
Louis's avatar
Louis committed

pub fn set_instructions(
	mut instructions: Query<&mut Text, (With<TextMarker>, Without<DetailsMarker>)>,
	mut details: Query<&mut Text, (With<DetailsMarker>, Without<TextMarker>)>,
) {
	for mut text in &mut instructions {
		text.sections[0].value = String::from("Press Right Shift To Change Tracks")
	}
	for mut text in &mut details {
		text.sections[0].value = String::from("Press 1-9 to change volume (10% - 90%)")
	}
}

pub fn setup_audio(mut commands: Commands, mut musicbox: MusicBox<AssetServer>) {
	musicbox.play_music("The-White-Kitty.mp3");
	commands.insert_resource(MusicState {
		playing_first: true,
	});
}

// pub fn

pub fn cross_fade_tracks(
	input: Res<Input<KeyCode>>,
	mut music_box: MusicBox<AssetServer>,
	mut music_state: ResMut<MusicState>,
) {
	if input.just_released(KeyCode::RShift) {
		if music_state.playing_first {
			music_box.cross_fade_music(
				"The-Great-Madeja.mp3",
				AudioTween::new(Duration::from_millis(500), AudioEasing::InOutPowf(0.6)),
			);
		} else {
			music_box.cross_fade_music(
				"The-White-Kitty.mp3",
				AudioTween::new(Duration::from_millis(500), AudioEasing::InOutPowf(0.6)),
			);
		}
		music_state.playing_first = !music_state.playing_first;
	}

	if let Some(value) = map_key_values(&input) {
		//
		// You can set the volume of a channel with a convenience method
		//
		music_box.set_music_volume(value as f32 / 10.0);
	}

	if input.just_released(KeyCode::Return) {
		//
		// You can also get a mutable ref for the settings, in case you
		// need to do any maths with them. If you don't need `MusicBox`
		// in a system, then you can directly access the settings with
		// `Res<AudioSettings>`, or the ResMut equivalent
		//
		let mut settings = music_box.settings_mut();
		if settings.master_volume < 1.0 {
			settings.master_volume = 1.0;
		} else {
			settings.master_volume = 0.5;
		}
	}
}

fn map_key_values(input: &Res<Input<KeyCode>>) -> Option<usize> {
	if input.just_released(KeyCode::Key1) {
		Some(1)
	} else if input.just_released(KeyCode::Key2) {
		Some(2)
	} else if input.just_released(KeyCode::Key3) {
		Some(3)
	} else if input.just_released(KeyCode::Key4) {
		Some(4)
	} else if input.just_released(KeyCode::Key5) {
		Some(5)
	} else if input.just_released(KeyCode::Key6) {
		Some(6)
	} else if input.just_released(KeyCode::Key7) {
		Some(7)
	} else if input.just_released(KeyCode::Key8) {
		Some(8)
	} else if input.just_released(KeyCode::Key9) {
		Some(9)
	} else {
		None
	}
}