|
use tetra::audio::{self, Sound, SoundInstance}; |
|
use tetra::input::{self, Key}; |
|
use tetra::{Context, ContextBuilder, State}; |
|
|
|
struct SoundPool { |
|
// This isn't used, but you could hold onto it in case you want |
|
// to resize your pool later? |
|
sound: Sound, |
|
|
|
instances: Vec<SoundInstance>, |
|
next: usize, |
|
} |
|
|
|
impl SoundPool { |
|
fn new(ctx: &Context, sound: Sound, instance_count: usize) -> tetra::Result<SoundPool> { |
|
let mut instances = Vec::with_capacity(instance_count); |
|
|
|
for _ in 0..instance_count { |
|
instances.push(sound.spawn(ctx)?); |
|
} |
|
|
|
Ok(SoundPool { |
|
sound, |
|
instances, |
|
next: 0, |
|
}) |
|
} |
|
|
|
fn play(&mut self) { |
|
let instance = &self.instances[self.next]; |
|
|
|
// If we've looped back to an instance before it stops playing, |
|
// rewind it and play again. |
|
instance.stop(); |
|
instance.play(); |
|
|
|
self.next = (self.next + 1) % self.instances.len(); |
|
} |
|
} |
|
|
|
struct GameState { |
|
pool: SoundPool, |
|
} |
|
|
|
impl GameState { |
|
fn new(ctx: &mut Context) -> tetra::Result<GameState> { |
|
audio::set_master_volume(ctx, 0.4); |
|
|
|
let sound = Sound::new("./examples/resources/powerup.wav")?; |
|
let pool = SoundPool::new(ctx, sound, 3)?; |
|
|
|
Ok(GameState { pool }) |
|
} |
|
} |
|
|
|
impl State for GameState { |
|
fn update(&mut self, ctx: &mut Context) -> tetra::Result { |
|
if input::is_key_pressed(ctx, Key::Space) { |
|
self.pool.play(); |
|
} |
|
|
|
Ok(()) |
|
} |
|
} |
|
|
|
fn main() -> tetra::Result { |
|
ContextBuilder::new("Pooling Sounds", 640, 480) |
|
.build()? |
|
.run(GameState::new) |
|
} |