diff --git a/life/src/main.rs b/life/src/main.rs index ae559b0..012c5f3 100644 --- a/life/src/main.rs +++ b/life/src/main.rs @@ -2,7 +2,10 @@ use std::time::Duration; -use bevy::{audio::Volume, picking::hover::Hovered, platform::collections::HashMap}; +use bevy::{ + audio::Volume, input::mouse::{AccumulatedMouseMotion, MouseMotion}, picking::hover::Hovered, + platform::collections::HashMap, +}; use engine::*; const TILE: &str = "tileGrey_01.png"; @@ -30,7 +33,7 @@ fn main() { ) .add_systems( Update, - modulate_volume // TODO: .run_if(any_component_added::) + modulate_volume, // TODO: .run_if(any_component_added::) ) .add_systems(Update, grid_gizmo) .add_systems( @@ -53,10 +56,6 @@ fn main() { .run_if(in_state(SimulationState::Run)) .run_if(cooldown_secs(FRAME_DURATION)), ) - .add_systems( - Update, - start_audio_synced.run_if(cooldown_secs(FRAME_DURATION)) - ) .add_systems( Update, simulation_step.run_if(on_message::), @@ -66,6 +65,7 @@ fn main() { visualize_ui_state.run_if(on_message::>), ) .add_systems(Update, cell_lifecycle.run_if(on_message::)) + .add_systems(Update, mouse_pan.run_if(on_message::)) .add_observer(on_add_ui_button) .add_observer(on_add_coordinates) .run(); @@ -166,11 +166,14 @@ fn setup(mut commands: Commands) { )) .with_children(|parent| { parent.spawn(UiButton::Power).observe(shutdown); + // TODO: Play/Pause Toggle parent.spawn(UiButton::Pause).observe(pause_sim); - parent.spawn(UiButton::Step).observe(step_sim); parent.spawn(UiButton::Play).observe(play_sim); + parent.spawn(UiButton::Step).observe(step_sim); parent.spawn(UiButton::ZoomOut).observe(zoom_out); parent.spawn(UiButton::ZoomIn).observe(zoom_in); + // TODO: Reset button + // TODO: Mute/Unmute Toggle }); fn shutdown(_trigger: On>, mut writer: MessageWriter) { @@ -261,7 +264,7 @@ impl Coordinates { fn as_color(&self) -> Color { // hue (0..360.0) evenly spaced x in -2..4 // chroma (0..1) evenly spaced y in -2..5 - let hue = (360.0 / 5.0) * ((self.x + 2) % 5) as f32; + let hue = (360.0 / 5.0) * ((self.x + 2) % 5) as f32; let chroma = (1.0 / 5.0) * ((self.y + 2) % 5) as f32; let lightness = (1.0 / 5.0) * ((self.y + 2) % 5) as f32; Color::Oklcha(Oklcha { @@ -272,7 +275,6 @@ impl Coordinates { }) } - fn as_cell_pitch(&self) -> CellPitch { debug!("Generating cell pitch for {:?}", self); @@ -288,11 +290,15 @@ impl Coordinates { let octave = ((self.y + 2).abs() % 5) - 2; debug_assert!((-2..=2).contains(&octave)); - debug!("\t{:?}", CellPitch { note: note.clone(), octave }); + debug!( + "\t{:?}", + CellPitch { + note: note.clone(), + octave + } + ); - CellPitch { - note, octave - } + CellPitch { note, octave } } } @@ -324,17 +330,9 @@ fn on_add_coordinates( commands.entity(trigger.entity).insert(t); let p = cell_assets.pitches.get(&c.as_cell_pitch()).unwrap(); - commands.entity(trigger.entity).insert((AudioPlayer(p.clone()), PlaybackSettings::ONCE)); -} - -/// All audio starts paused so we can keep them in sync -/// This starts audios when the system is triggered, which is on a timer -fn start_audio_synced(query: Query<&AudioSink, With>) { - query.iter().for_each(|sink| { - if sink.is_paused() { - sink.play() - } - }); + commands + .entity(trigger.entity) + .insert((AudioPlayer(p.clone()), PlaybackSettings::ONCE)); } /// When the cursor moves, update the Coordiantes @@ -603,6 +601,10 @@ fn load_audio_tones(mut pitches: ResMut>, mut cell_assets: ResMut< }; let frequency = cell_pitch.to_frequency(); let duration = Duration::from_secs(100); + debug!( + "Adding Pitch frequency: {:?} duration: {:?}", + frequency, duration + ); let handle = pitches.add(Pitch { frequency, duration, @@ -613,6 +615,7 @@ fn load_audio_tones(mut pitches: ResMut>, mut cell_assets: ResMut< debug_assert!(cell_assets.pitches.iter().len() == 25); } +// TODO: Why does audio only play when running simulation? fn modulate_volume(mut gv: ResMut, active: Query>) { let ratio = 1.0 / active.count() as f32; gv.volume = Volume::Linear(ratio); @@ -630,11 +633,15 @@ fn load_materials( vertical.iter().for_each(|&x| { horizontal.iter().for_each(|&y| { let c = Coordinates { x, y }; - let pitch = c.as_cell_pitch(); + let pitch = c.as_cell_pitch(); let handle = { let color = c.as_color(); let texture = Some(tile_handle.clone()); - let color_material = ColorMaterial { color, texture, ..default() }; + let color_material = ColorMaterial { + color, + texture, + ..default() + }; materials.add(color_material) }; cell_assets.materials.insert(pitch, handle); @@ -646,3 +653,35 @@ fn load_materials( fn load_meshes(mut cell_assets: ResMut, mut meshes: ResMut>) { cell_assets.mesh = meshes.add(Rectangle::new(SCALE, SCALE)); } + +// TODO: Do not place piece if panning +// TODO: Tie cursor to real world space, not pixels +fn mouse_pan( + mouse_motion: Res, + button: Res>, + mut camera: Query<(&Camera, &mut Transform, &GlobalTransform), With>, + window: Query<&Window>, +) { + if button.pressed(MouseButton::Left) { + let delta = mouse_motion.delta; + camera.iter_mut().for_each(|(c, mut t, gt)| { + window.iter().for_each(|w| { + let Some(curr_cursor_position) = w.cursor_position() else { + return; + }; + let old_cursor_position = curr_cursor_position - delta / w.scale_factor(); + + let Ok(curr_world) = c.viewport_to_world_2d(gt, curr_cursor_position) else { + return; + }; + let Ok(old_world) = c.viewport_to_world_2d(gt, old_cursor_position) else { + return; + }; + + let delta_world = old_world - curr_world; + t.translation.x += delta_world.x / 7.0; + t.translation.y += delta_world.y / 7.0; + }); + }); + } +} diff --git a/prototypes/src/bin/example.rs b/prototypes/src/bin/example.rs new file mode 100644 index 0000000..8e09559 --- /dev/null +++ b/prototypes/src/bin/example.rs @@ -0,0 +1,5 @@ +use engine::*; + +fn main() { + App::new().add_plugins(DefaultPlugins).run(); +} diff --git a/scripts/fmt b/scripts/fmt index b7e9bf5..2cf40fd 100755 --- a/scripts/fmt +++ b/scripts/fmt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -for dir in $(find . -mindepth 2 -maxdepth 2 -name "Cargo.toml" -not -path "*/target/*" -exec dirname {} \;); +for dir in $(find . -mindepth 2 -maxdepth 2 -name "Cargo.toml" -not -path "*/target/*" | xargs -I{} dirname {} ); do cargo fmt --manifest-path "$dir/Cargo.toml"; done