outfly/src/audio.rs
2024-03-31 01:35:37 +01:00

220 lines
7.2 KiB
Rust

use bevy::prelude::*;
use bevy::audio::{PlaybackMode, Volume};
use crate::settings;
const ASSET_CLICK: &str = "sounds/click-button-140881-crop.ogg";
const ASSET_SWITCH: &str = "sounds/typosonic-typing-192811-crop.ogg";
const ASSET_INCOMING_MESSAGE: &str = "sounds/connect.ogg";
const ASSET_PING: &str = "sounds/connect.ogg";
const ASSET_CONNECT: &str = "sounds/connect.ogg";
const ASSET_BGM: &str = "music/dead-space-style-ambient-music.ogg";
const ASSET_THRUSTER: &str = "sounds/thruster.ogg";
const ASSET_ROCKET: &str = "sounds/rocket.ogg";
const ASSET_ION: &str = "sounds/ion.ogg";
//const ASSET_WAKEUP: &str = "sounds/wakeup.ogg";
const ASSET_BIKESTART: &str = "sounds/bikestart.ogg";
const ASSET_CRASH: &str = "sounds/crash.ogg";
const ASSET_ELECTRICMOTOR: &str = "sounds/electricmotor.ogg";
pub struct AudioPlugin;
impl Plugin for AudioPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup);
app.add_systems(Update, toggle_bgm);
app.add_systems(PostUpdate, play_sfx);
app.add_systems(PostUpdate, update_music);
app.add_event::<PlaySfxEvent>();
app.add_event::<ToggleMusicEvent>();
}
}
pub enum Sfx {
IncomingChatMessage,
Click,
Switch,
Ping,
Connect,
EnterVehicle,
Crash,
None,
}
#[derive(Event)] pub struct PlaySfxEvent(pub Sfx);
#[derive(Event)] pub struct ToggleMusicEvent();
#[derive(Component)] pub struct ComponentBGM;
#[derive(Component)] pub struct ComponentThrusterSound;
#[derive(Component)] pub struct ComponentRocketSound;
#[derive(Component)] pub struct ComponentIonSound;
#[derive(Component)] pub struct ComponentElectricMotorSound;
#[derive(Component)] struct SoundBGM(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundClick(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundSwitch(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundIncomingMessage(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundPing(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundConnect(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundBikeStart(Handle<AudioSource>);
#[derive(Resource)] pub struct SoundCrash(Handle<AudioSource>);
pub fn setup(
mut commands: Commands,
settings: Res<settings::Settings>,
asset_server: Res<AssetServer>,
) {
commands.spawn((
ComponentBGM,
AudioBundle {
source: SoundBGM(asset_server.load(ASSET_BGM)).0.clone(),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: settings.hud_active || settings.mute_music,
..default()
},
},
));
//if !settings.mute_sfx {
// commands.spawn((
// AudioBundle {
// source: asset_server.load(ASSET_WAKEUP),
// settings: PlaybackSettings::DESPAWN,
// },
// ));
//}
commands.spawn((
ComponentThrusterSound,
AudioBundle {
source: asset_server.load(ASSET_THRUSTER),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: true,
..default()
},
},
));
commands.spawn((
ComponentRocketSound,
AudioBundle {
source: asset_server.load(ASSET_ROCKET),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: true,
..default()
},
},
));
commands.spawn((
ComponentIonSound,
AudioBundle {
source: asset_server.load(ASSET_ION),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: true,
..default()
},
},
));
commands.spawn((
ComponentElectricMotorSound,
AudioBundle {
source: asset_server.load(ASSET_ELECTRICMOTOR),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
volume: Volume::new(0.5),
paused: true,
..default()
},
},
));
commands.insert_resource(SoundClick(asset_server.load(ASSET_CLICK)));
commands.insert_resource(SoundSwitch(asset_server.load(ASSET_SWITCH)));
commands.insert_resource(SoundIncomingMessage(asset_server.load(ASSET_INCOMING_MESSAGE)));
commands.insert_resource(SoundPing(asset_server.load(ASSET_PING)));
commands.insert_resource(SoundConnect(asset_server.load(ASSET_CONNECT)));
commands.insert_resource(SoundBikeStart(asset_server.load(ASSET_BIKESTART)));
commands.insert_resource(SoundCrash(asset_server.load(ASSET_CRASH)));
}
pub fn toggle_bgm(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut evwriter_toggle: EventWriter<ToggleMusicEvent>,
mut evwriter_sfx: EventWriter<PlaySfxEvent>,
mut settings: ResMut<settings::Settings>,
) {
if keyboard_input.just_pressed(KeyCode::KeyT) {
settings.mute_music ^= true;
evwriter_sfx.send(PlaySfxEvent(Sfx::Click));
evwriter_toggle.send(ToggleMusicEvent());
}
if keyboard_input.just_pressed(KeyCode::KeyM) {
settings.mute_sfx ^= true;
evwriter_sfx.send(PlaySfxEvent(Sfx::Click));
evwriter_toggle.send(ToggleMusicEvent());
}
}
pub fn play_sfx(
mut commands: Commands,
settings: Res<settings::Settings>,
mut events_sfx: EventReader<PlaySfxEvent>,
sound_click: Res<SoundClick>,
sound_switch: Res<SoundSwitch>,
sound_incoming_message: Res<SoundIncomingMessage>,
sound_ping: Res<SoundPing>,
sound_connect: Res<SoundConnect>,
sound_bikestart: Res<SoundBikeStart>,
sound_crash: Res<SoundCrash>,
) {
if settings.mute_sfx && !events_sfx.is_empty() {
events_sfx.clear();
}
for sfx in events_sfx.read() {
match sfx.0 {
Sfx::None => { continue; }
_ => {}
}
commands.spawn(AudioBundle {
source: match sfx.0 {
Sfx::Switch => sound_switch.0.clone(),
Sfx::Click => sound_click.0.clone(),
Sfx::IncomingChatMessage => sound_incoming_message.0.clone(),
Sfx::Ping => sound_ping.0.clone(),
Sfx::Connect => sound_connect.0.clone(),
Sfx::EnterVehicle => sound_bikestart.0.clone(),
Sfx::Crash => sound_crash.0.clone(),
Sfx::None => sound_ping.0.clone(),
},
settings: PlaybackSettings::DESPAWN,
});
}
}
pub fn str2sfx(sfx_label: &str) -> Sfx {
return match sfx_label {
"switch" => Sfx::Switch,
"click" => Sfx::Click,
"chat" => Sfx::IncomingChatMessage,
"ping" => Sfx::Ping,
"connect" => Sfx::Connect,
"entervehicle" => Sfx::EnterVehicle,
"crash" => Sfx::Crash,
_ => Sfx::None,
};
}
pub fn update_music(
mut events: EventReader<ToggleMusicEvent>,
bgm_controller: Query<&AudioSink, With<ComponentBGM>>,
settings: Res<settings::Settings>,
) {
if !events.is_empty() {
events.clear();
if let Ok(bgm_sink) = bgm_controller.get_single() {
if settings.mute_music {
bgm_sink.pause();
}
else {
bgm_sink.play();
}
}
}
}