From dd1d55acea651ff087cbddde54ad355dc344f49c Mon Sep 17 00:00:00 2001 From: Matthew Kousoulas Date: Sat, 19 Oct 2024 00:00:40 -0400 Subject: [PATCH] WIP scroll zoom --- src/TODO | 13 +++++++++++ src/camera.rs | 62 ++++++++++++------------------------------------- src/control.rs | 42 +++++++++++++++++++++++++++++---- src/main.rs | 46 +++++++++++++++++++++++++----------- src/particle.rs | 5 +++- 5 files changed, 101 insertions(+), 67 deletions(-) create mode 100644 src/TODO diff --git a/src/TODO b/src/TODO new file mode 100644 index 0000000..a2aa942 --- /dev/null +++ b/src/TODO @@ -0,0 +1,13 @@ +particle types: + locomotive + offensive/defensive + +game flow: + +display: + statistic graphs + paused overlay + +camera controls: + center (selected, origin) + diff --git a/src/camera.rs b/src/camera.rs index 4451673..a24e800 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -5,17 +5,11 @@ pub struct CameraCfg; #[derive(Component)] pub struct MainCamera; -//#[derive(Event)] -//pub struct PanCamera(pub Vec2); -//#[derive(Event)] -//pub struct ZoomCamera(pub f32); -//#[derive(Event)] -//pub struct RotateCamera(pub f32); - #[derive(Event)] pub enum MoveCamera { Pan(Vec2), Zoom(f32), + ZoomTo(Option, f32), Rotate(f32), Center(Vec2), Reset, @@ -23,16 +17,10 @@ pub enum MoveCamera { impl Plugin for CameraCfg { fn build(&self, app: &mut App) { - //app.add_event::(); - //app.add_event::(); - //app.add_event::(); app.add_event::(); app.add_systems(Startup, setup); app.add_systems(Update, ( move_camera.run_if(on_event::()), - //pan_camera.run_if(on_event::()), - //zoom_camera.run_if(on_event::()), - //rotate_camera.run_if(on_event::()), )); } } @@ -45,9 +33,9 @@ fn setup( fn move_camera( mut e_read: EventReader, - mut camera: Query<(&mut Transform, &mut OrthographicProjection), With> + mut camera: Query<(&Camera, &GlobalTransform, &mut Transform, &mut OrthographicProjection), With> ) { - let Ok((mut trans, mut proj)) = camera.get_single_mut() else { return; }; + let Ok((camera, gtrans, mut trans, mut proj)) = camera.get_single_mut() else { return; }; let z = trans.translation.z; for mov in e_read.read() { match mov { @@ -56,6 +44,18 @@ fn move_camera( trans.translation += r; }, MoveCamera::Zoom(z) => proj.scale += z * proj.scale, + MoveCamera::ZoomTo(o, z) => { + info!("Raw {:?}", o); + let p = match o.and_then(|p| camera.viewport_to_world_2d(gtrans, p)) { + Some(p) => p, + None => Vec2::ZERO, + }; + info!("Proc {:?}", p); + info!("Origin {:?}", proj.viewport_origin); + proj.viewport_origin = p;//Vec2::new(p.x / window.width() + 0.5, 0.5 - p.y / window.height()); + proj.scale += z * proj.scale; + proj.viewport_origin = Vec2::ZERO; + }, MoveCamera::Rotate(th) => trans.rotation *= Quat::from_rotation_z(*th), MoveCamera::Center(p) => trans.translation = Vec3::from((*p, z)), MoveCamera::Reset => { @@ -66,35 +66,3 @@ fn move_camera( } } } - -//fn pan_camera( -// mut e_read: EventReader, -// mut camera: Query<&mut Transform, With> -//) { -// let Ok(mut camera) = camera.get_single_mut() else { return; }; -// let z = camera.translation.z; -// for PanCamera(p) in e_read.read() { -// camera.translation += Vec3::from((*p, z)); -// } -//} -// -//fn zoom_camera( -// mut e_read: EventReader, -// mut camera: Query<&mut OrthographicProjection, With> -//) { -// //use bevy::render::camera::ScalingMode; -// let Ok(mut camera) = camera.get_single_mut() else { return; }; -// for ZoomCamera(z) in e_read.read() { -// camera.scale += z; -// } -//} -// -//fn rotate_camera( -// mut e_read: EventReader, -// mut camera: Query<&mut Transform, With> -//) { -// let Ok(mut camera) = camera.get_single_mut() else { return; }; -// for RotateCamera(th) in e_read.read() { -// camera.rotation *= Quat::from_rotation_z(*th); -// } -//} diff --git a/src/control.rs b/src/control.rs index 612e8cd..5f148d8 100644 --- a/src/control.rs +++ b/src/control.rs @@ -5,12 +5,15 @@ use crate::camera::*; use crate::PausedState; const PAN_SLOW: f32 = 4.0; +const PAN_FAST: f32 = 16.0; const ZOOM_SLOW: f32 = 1.0 / 128.0; +const ZOOM_FAST: f32 = 1.0 / 32.0; const ROTATE_SLOW: f32 = PI / 512.0; -const PAN_FAST: f32 = 1.0 / 32.0; -const ZOOM_FAST: f32 = 0.03125; const ROTATE_FAST: f32 = PI / 128.0; +const SCROLL_LINE_FACTOR: f32 = 1.0; +const SCROLL_PIXEL_FACTOR: f32 = 10.0; + pub struct Controls; impl Plugin for Controls { @@ -18,6 +21,8 @@ impl Plugin for Controls { app.add_systems(Update, ( handle_pause, handle_camera_input, + handle_camera_scroll, + //handle_camera_drag, )); } } @@ -35,12 +40,39 @@ fn handle_pause( } } +use bevy::window::PrimaryWindow; +use bevy::input::mouse::*; +fn handle_camera_scroll( + window: Query<&Window, With>, + mut scroll_events: EventReader, + mut e_write: EventWriter, +) { + let window = window.single(); + + for scroll in scroll_events.read() { + let factor = match scroll.unit { + MouseScrollUnit::Pixel => SCROLL_PIXEL_FACTOR, + MouseScrollUnit::Line => SCROLL_LINE_FACTOR, + }; + + //proj.viewport_origin = Vec2::new(p.x / window.width() + 0.5, 0.5 - p.y / window.height()); + e_write.send(MoveCamera::ZoomTo(window.cursor_position(), ZOOM_FAST * -scroll.y * factor)); + } +} + +//fn handle_camera_drag( +// mouse_button: Res>, +// mut motion_events: EventReader, +// mut e_write: EventWriter, +//) { +// for motion in motion_events.read() { +// +// } +//} + fn handle_camera_input( keyboard_input: Res>, mut e_write: EventWriter, - //mut e_pan: EventWriter, - //mut e_zoom: EventWriter, - //mut e_rotate: EventWriter, ) { let fast = keyboard_input.pressed(KeyCode::ShiftLeft) || keyboard_input.pressed(KeyCode::ShiftRight); diff --git a/src/main.rs b/src/main.rs index 7670538..0456050 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,4 @@ -use bevy::{ - prelude::*, -}; +use bevy::prelude::*; mod physics; mod particle; @@ -34,24 +32,50 @@ enum PausedState { fn main() { App::new() .add_plugins(DefaultPlugins) - .add_event::() - .add_event::() + .init_state::() .add_systems(Startup, setup) .add_systems(Update, ( + cursor, handle_click, - write_diagnostics, + //write_diagnostics, find_select_particle.run_if(on_event::()), process_select_particle.run_if(on_event::