|
|
|
|
@ -496,13 +496,30 @@ enum Lifecycle {
|
|
|
|
|
Dead(Entity),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_cell(Coordinates { x, y }: Coordinates, cell_assets: &Res<CellAssets>) -> impl Scene {
|
|
|
|
|
fn new_cell(
|
|
|
|
|
Coordinates { x, y }: Coordinates,
|
|
|
|
|
cell_assets: &Res<CellAssets>,
|
|
|
|
|
sinks: &Query<Entity, With<AudioSink>>,
|
|
|
|
|
sim_state: &Res<State<SimulationPlayback>>,
|
|
|
|
|
audio_state: &Res<State<AudioPlayback>>,
|
|
|
|
|
) -> impl Scene {
|
|
|
|
|
let c = Coordinates { x, y };
|
|
|
|
|
|
|
|
|
|
let volume = {
|
|
|
|
|
if *sim_state.get() == SimulationPlayback::Run && *audio_state.get() == AudioPlayback::Play {
|
|
|
|
|
let ratio = 1.0 / (sinks.count() + 1) as f32;
|
|
|
|
|
Volume::Linear(ratio)
|
|
|
|
|
} else {
|
|
|
|
|
Volume::SILENT
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let playback_settings = PlaybackSettings::ONCE.with_volume(volume);
|
|
|
|
|
|
|
|
|
|
bsn! {
|
|
|
|
|
Cell
|
|
|
|
|
Coordinates { x, y }
|
|
|
|
|
PlaybackSettings::ONCE
|
|
|
|
|
template_value(playback_settings)
|
|
|
|
|
template_value(Transform::from_translation(c.as_translation() + Vec3::new(0.0, 0.0, 1.0)))
|
|
|
|
|
template_value(AudioPlayerTemplate(cell_assets.pitches.get(&c.as_cell_pitch()).unwrap().clone().into()))
|
|
|
|
|
template_value(Mesh2dTemplate(cell_assets.mesh.clone().into()))
|
|
|
|
|
@ -514,12 +531,21 @@ fn cell_lifecycle(
|
|
|
|
|
mut reader: MessageReader<Lifecycle>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
cell_assets: Res<CellAssets>,
|
|
|
|
|
query: Query<Entity, With<AudioSink>>,
|
|
|
|
|
sim_state: Res<State<SimulationPlayback>>,
|
|
|
|
|
audio_state: Res<State<AudioPlayback>>,
|
|
|
|
|
) {
|
|
|
|
|
reader.read().for_each(|msg| match msg {
|
|
|
|
|
Lifecycle::Alive(c) => {
|
|
|
|
|
debug!("creating {:?}", c);
|
|
|
|
|
// TODO: Safeguard: ensure no other cell there?
|
|
|
|
|
commands.spawn_scene(new_cell(c.clone(), &cell_assets));
|
|
|
|
|
commands.spawn_scene(new_cell(
|
|
|
|
|
c.clone(),
|
|
|
|
|
&cell_assets,
|
|
|
|
|
&query,
|
|
|
|
|
&sim_state,
|
|
|
|
|
&audio_state,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
Lifecycle::Dead(e) => {
|
|
|
|
|
commands.entity(*e).despawn();
|
|
|
|
|
@ -632,17 +658,28 @@ fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<
|
|
|
|
|
debug_assert!(cell_assets.pitches.iter().len() == 25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn control_volume(state: ResMut<State<AudioPlayback>>, mut sinks: Query<&mut AudioSink>) {
|
|
|
|
|
match state.get() {
|
|
|
|
|
AudioPlayback::Play => {
|
|
|
|
|
fn control_volume(
|
|
|
|
|
audio_state: Res<State<AudioPlayback>>,
|
|
|
|
|
simulation_state: Res<State<SimulationPlayback>>,
|
|
|
|
|
mut sinks: Query<&mut AudioSink>,
|
|
|
|
|
) {
|
|
|
|
|
match audio_state.get() {
|
|
|
|
|
AudioPlayback::Play => match simulation_state.get() {
|
|
|
|
|
SimulationPlayback::Run => {
|
|
|
|
|
let ratio = 1.0 / sinks.count() as f32;
|
|
|
|
|
let volume = Volume::Linear(ratio);
|
|
|
|
|
sinks.iter_mut().for_each(|mut sink| {
|
|
|
|
|
sinks.par_iter_mut().for_each(|mut sink| {
|
|
|
|
|
sink.set_volume(volume);
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
AudioPlayback::Mute => sinks.iter_mut().for_each(|mut sink| {
|
|
|
|
|
sink.set_volume(Volume::SILENT);
|
|
|
|
|
SimulationPlayback::Pause | SimulationPlayback::Step => {
|
|
|
|
|
sinks.par_iter_mut().for_each(|mut sink| {
|
|
|
|
|
sink.mute();
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
AudioPlayback::Mute => sinks.par_iter_mut().for_each(|mut sink| {
|
|
|
|
|
sink.mute();
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|