use bevy::prelude::*; use bevy::audio::PlaybackMode; const ASSET_CLICK: &str = "sounds/click-button-140881-crop.ogg"; const ASSET_SWITCH: &str = "sounds/typosonic-typing-192811-crop.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_event::(); app.add_event::(); } } #[derive(Event)] pub struct AudioClickEvent(); #[derive(Event)] pub struct AudioSwitchEvent(); #[derive(Component)] pub struct ComponentBGM; #[derive(Component)] pub struct ComponentThrusterSound; #[derive(Resource)] struct SoundBGM(Handle); #[derive(Resource)] pub struct SoundClick(Handle); #[derive(Resource)] pub struct SoundSwitch(Handle); pub fn setup( mut commands: Commands, asset_server: Res, ) { let bgm = SoundBGM(asset_server.load("tmp/FTL - Faster Than Light (2012) OST - 12 - Void (Explore)-edQw2yYXQJM.ogg")); commands.spawn(( AudioBundle { source: bgm.0.clone(), settings: PlaybackSettings::LOOP, }, ComponentBGM, )); commands.insert_resource(bgm); commands.spawn(( AudioBundle { source: asset_server.load("sounds/wakeup.ogg"), settings: PlaybackSettings::DESPAWN, }, )); commands.spawn(( ComponentThrusterSound, AudioBundle { source: asset_server.load("tmp/loopingthrust-95548.ogg"), settings: PlaybackSettings { mode: PlaybackMode::Loop, paused: true, ..default() }, }, )); commands.insert_resource(SoundClick(asset_server.load(ASSET_CLICK))); commands.insert_resource(SoundSwitch(asset_server.load(ASSET_SWITCH))); } pub fn toggle_bgm( keyboard_input: Res>, bgm_controller: Query<&AudioSink, With>, mut evwriter: EventWriter, ) { if keyboard_input.just_pressed(KeyCode::KeyT) { if let Ok(sink) = bgm_controller.get_single() { sink.toggle(); evwriter.send(AudioClickEvent()); } } } pub fn play_sfx( mut commands: Commands, mut events_click: EventReader, mut events_switch: EventReader, sound_click: Res, sound_switch: Res, ) { if !events_click.is_empty() { events_click.clear(); commands.spawn(AudioBundle { source: sound_click.0.clone(), settings: PlaybackSettings::DESPAWN, }); } if !events_switch.is_empty() { events_switch.clear(); commands.spawn(AudioBundle { source: sound_switch.0.clone(), settings: PlaybackSettings::DESPAWN, }); } }