Now in order to play the sound the wav files need to be loaded. To avoid loading them on the fly every time before we play the sound we'll create an audio store and load them up at the beginning of the game.
And let's add the code for initializing the store, which means pre-loading all the sounds needed for the game.
#![allow(unused)]fnmain() {
pubfnload_sounds(world: &mut World, context: &mut Context) {
letmut query = world.query::<&mut crate::components::AudioStore>();
let audio_store = query.iter().next().unwrap().1;
let sounds = ["correct", "incorrect", "wall"];
for sound in sounds.iter() {
let sound_name = sound.to_string();
let sound_path = format!("/sounds/{}.wav", sound_name);
let sound_source = Source::new(context, sound_path).expect("expected sound loaded");
audio_store
.sounds
.insert(sound_name, Box::new(sound_source));
}
}
}
And then call this function when we are initializing the level.
#![allow(unused)]fnmain() {
pubfninitialize_level(world: &mut World, context: &mut Context) {
const MAP: &str = "
N N W W W W W W
W W W . . . . W
W . . . BB . . W
W . . RB . . . W
W . P . . . . W
W . . . . RS . W
W . . BS . . . W
W . . . . . . W
W W W W W W W W
";
load_map(world, MAP.to_string());
load_sounds(world, context);
}
}
#![allow(unused)]fnmain() {
// systems/events.rsuse crate::components::*;
use crate::events::*;
use ggez::Context;
use hecs::World;
use std::collections::HashMap;
pubfnrun_process_events(world: &mut World, context: &mut Context) {
let events = {
letmut query = world.query::<&mut crate::components::EventQueue>();
let events = query
.iter()
.next()
.unwrap()
.1
.events
.drain(..)
.collect::<Vec<_>>();
events
};
letmut new_events = Vec::new();
letmut query = world.query::<(&Position, &BoxSpot)>();
let box_spots_by_position: HashMap<(u8, u8), &BoxSpot> = query
.iter()
.map(|(_, t)| ((t.0.x, t.0.y), t.1))
.collect::<HashMap<_, _>>();
letmut query = world.query::<&mut AudioStore>();
let audio_store = query.iter().next().unwrap().1;
for event in events {
println!("New event: {:?}", event);
match event {
Event::PlayerHitObstacle => {
// play sound here
audio_store.play_sound(context, "wall");
}
Event::EntityMoved(EntityMoved { entity }) => {
// An entity was just moved, check if it was a box and fire// more events if it's been moved on a spot.ifletOk(the_box) = world.get::<&Box>(entity) {
ifletOk(box_position) = world.get::<&Position>(entity) {
// Check if there is a spot on this position, and if there// is if it's the correct or incorrect typeifletSome(box_spot) =
box_spots_by_position.get(&(box_position.x, box_position.y))
{
new_events.push(Event::BoxPlacedOnSpot(BoxPlacedOnSpot {
is_correct_spot: (box_spot.colour == the_box.colour),
}));
}
}
}
}
Event::BoxPlacedOnSpot(BoxPlacedOnSpot { is_correct_spot }) => {
// play sound herelet sound = if is_correct_spot {
"correct"
} else {
"incorrect"
};
audio_store.play_sound(context, sound);
}
}
}
// Finally add events back into the world
{
letmut query = world.query::<&mut EventQueue>();
let event_queue = query.iter().next().unwrap().1;
event_queue.events.append(&mut new_events);
}
}
}
Now let's run the game and enjoy those sound effects!
CODELINK: You can see the full code in this example here.