|
|
|
|
@ -1,3 +1,7 @@
|
|
|
|
|
#![allow(clippy::complexity)]
|
|
|
|
|
// Only because of FromTemplat macros unfortunately...
|
|
|
|
|
#![allow(dead_code)]
|
|
|
|
|
|
|
|
|
|
use bevy::{
|
|
|
|
|
feathers::{containers::*, theme::ThemeProps},
|
|
|
|
|
ui::{Checked, InteractionDisabled},
|
|
|
|
|
@ -590,6 +594,7 @@ fn new_cell(
|
|
|
|
|
sinks: &Query<Entity, With<AudioSink>>,
|
|
|
|
|
sim_state: &Res<State<SimulationPlayback>>,
|
|
|
|
|
audio_state: &Res<State<AudioPlayback>>,
|
|
|
|
|
pitch_map: &Res<PitchMap>,
|
|
|
|
|
) -> impl Scene {
|
|
|
|
|
let c = Coordinates { x, y };
|
|
|
|
|
|
|
|
|
|
@ -605,14 +610,19 @@ fn new_cell(
|
|
|
|
|
|
|
|
|
|
let playback_settings = PlaybackSettings::ONCE.with_volume(volume);
|
|
|
|
|
|
|
|
|
|
info!("using coordinates {:?}", c);
|
|
|
|
|
info!("cell_pitch: {:?}", pitch_map.coordinates_cell_pitch(&c));
|
|
|
|
|
info!("pitch map {:?}", pitch_map);
|
|
|
|
|
info!("cell assets materials: {:#?}", cell_assets.materials);
|
|
|
|
|
|
|
|
|
|
bsn! {
|
|
|
|
|
Cell
|
|
|
|
|
Coordinates { x, y }
|
|
|
|
|
template_value(playback_settings)
|
|
|
|
|
template_value(Transform::from_translation(c.as_translation() + Vec3::new(0.0, 0.0, 1.0)))
|
|
|
|
|
template_value(Mesh2dTemplate(cell_assets.mesh.clone().into()))
|
|
|
|
|
// TODO: template_value(AudioPlayerTemplate(cell_assets.pitches.get(&pitch_map.coordinates_cell_pitch(c)).unwrap().clone().into()))
|
|
|
|
|
// TODO: template_value(MeshMaterial2dTemplate(cell_assets.materials.get(&pitch_map.coordinates_cell_pitch(c)).unwrap().clone().into()))
|
|
|
|
|
template_value(AudioPlayerTemplate(cell_assets.pitches.get(&pitch_map.coordinates_cell_pitch(&c)).unwrap().clone().into()))
|
|
|
|
|
template_value(MeshMaterial2dTemplate(cell_assets.materials.get(&pitch_map.coordinates_cell_pitch(&c)).unwrap().clone().into()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -623,6 +633,7 @@ fn cell_lifecycle(
|
|
|
|
|
query: Query<Entity, With<AudioSink>>,
|
|
|
|
|
sim_state: Res<State<SimulationPlayback>>,
|
|
|
|
|
audio_state: Res<State<AudioPlayback>>,
|
|
|
|
|
pitch_map: Res<PitchMap>,
|
|
|
|
|
) {
|
|
|
|
|
reader.read().for_each(|msg| match msg {
|
|
|
|
|
Lifecycle::Alive(c) => {
|
|
|
|
|
@ -634,6 +645,7 @@ fn cell_lifecycle(
|
|
|
|
|
&query,
|
|
|
|
|
&sim_state,
|
|
|
|
|
&audio_state,
|
|
|
|
|
&pitch_map,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
Lifecycle::Dead(e) => {
|
|
|
|
|
@ -657,7 +669,7 @@ fn cooldown_secs(input: f32) -> impl FnMut(Local<Timer>, Res<Time>) -> bool + Cl
|
|
|
|
|
// Scale grid with background?
|
|
|
|
|
// Pan camera: click and drag
|
|
|
|
|
|
|
|
|
|
#[derive(Resource, Default)]
|
|
|
|
|
#[derive(Resource, Default, Debug)]
|
|
|
|
|
struct CellAssets {
|
|
|
|
|
pitches: HashMap<CellPitch, Handle<Pitch>>,
|
|
|
|
|
materials: HashMap<CellPitch, Handle<ColorMaterial>>,
|
|
|
|
|
@ -759,10 +771,9 @@ impl CellPitch {
|
|
|
|
|
..default()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<CellAssets>) {
|
|
|
|
|
let notes = [
|
|
|
|
|
fn iter_all() -> impl Iterator<Item = Self> {
|
|
|
|
|
[
|
|
|
|
|
Note::A,
|
|
|
|
|
Note::ASharp,
|
|
|
|
|
Note::B,
|
|
|
|
|
@ -775,15 +786,19 @@ fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<
|
|
|
|
|
Note::FSharp,
|
|
|
|
|
Note::G,
|
|
|
|
|
Note::GSharp,
|
|
|
|
|
];
|
|
|
|
|
let octaves = -5..6;
|
|
|
|
|
|
|
|
|
|
octaves.for_each(|octave| {
|
|
|
|
|
notes.iter().for_each(|note| {
|
|
|
|
|
let cell_pitch = CellPitch {
|
|
|
|
|
].into_iter().flat_map(|note| {
|
|
|
|
|
(-5..6).map(move |octave| {
|
|
|
|
|
CellPitch {
|
|
|
|
|
note: note.clone(),
|
|
|
|
|
octave,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<CellAssets>) {
|
|
|
|
|
CellPitch::iter_all().for_each(|cell_pitch| {
|
|
|
|
|
let frequency = cell_pitch.to_frequency();
|
|
|
|
|
let duration = Duration::from_secs(100);
|
|
|
|
|
debug!(
|
|
|
|
|
@ -796,7 +811,6 @@ fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<
|
|
|
|
|
});
|
|
|
|
|
cell_assets.pitches.insert(cell_pitch, handle);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
debug_assert_eq!(cell_assets.pitches.iter().len(), 132);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -831,22 +845,11 @@ fn load_materials(
|
|
|
|
|
mut cell_assets: ResMut<CellAssets>,
|
|
|
|
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
|
|
|
) {
|
|
|
|
|
// Up to 11 octaves total
|
|
|
|
|
let vertical = -5..6;
|
|
|
|
|
debug_assert_eq!(vertical.len(), 11);
|
|
|
|
|
|
|
|
|
|
// 12 total colors supported
|
|
|
|
|
let horizontal = -6..6;
|
|
|
|
|
debug_assert_eq!(horizontal.len(), 12);
|
|
|
|
|
|
|
|
|
|
let tile_handle = server.load(TILE);
|
|
|
|
|
|
|
|
|
|
vertical.for_each(|x| {
|
|
|
|
|
horizontal.clone().for_each(|y| {
|
|
|
|
|
let c = Coordinates { x, y };
|
|
|
|
|
let pitch = c.to_cell_pitch();
|
|
|
|
|
CellPitch::iter_all().for_each(|cell_pitch| {
|
|
|
|
|
let handle = {
|
|
|
|
|
let color = pitch.to_color();
|
|
|
|
|
let color = cell_pitch.to_color();
|
|
|
|
|
let texture = Some(tile_handle.clone());
|
|
|
|
|
let color_material = ColorMaterial {
|
|
|
|
|
color,
|
|
|
|
|
@ -855,8 +858,7 @@ fn load_materials(
|
|
|
|
|
};
|
|
|
|
|
materials.add(color_material)
|
|
|
|
|
};
|
|
|
|
|
cell_assets.materials.insert(pitch, handle);
|
|
|
|
|
});
|
|
|
|
|
cell_assets.materials.insert(cell_pitch, handle);
|
|
|
|
|
});
|
|
|
|
|
debug_assert_eq!(cell_assets.materials.iter().len(), 132);
|
|
|
|
|
}
|
|
|
|
|
@ -945,7 +947,7 @@ fn toggle_interactive<T: Component + States + PartialEq>(
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Resource)]
|
|
|
|
|
#[derive(Resource, Debug)]
|
|
|
|
|
struct PitchMap {
|
|
|
|
|
notes: Vec<Note>,
|
|
|
|
|
octaves_up: usize,
|
|
|
|
|
|