]> MadKous Network Git Server - kytagony.git/commitdiff
WIP scroll zoom feature/scroll-zoom
authorMatthew Kousoulas <shaman.kous@gmail.com>
Sat, 19 Oct 2024 04:00:40 +0000 (00:00 -0400)
committerMatthew Kousoulas <shaman.kous@gmail.com>
Sat, 19 Oct 2024 04:00:40 +0000 (00:00 -0400)
src/TODO [new file with mode: 0644]
src/camera.rs
src/control.rs
src/main.rs
src/particle.rs

diff --git a/src/TODO b/src/TODO
new file mode 100644 (file)
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)
+
index 4451673b87a3f6d351b76ede21f12d128755a5d4..a24e800c10fac423114788126b3c788934a15ee0 100644 (file)
@@ -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<Vec2>, 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::<PanCamera>();
-               //app.add_event::<ZoomCamera>();
-               //app.add_event::<RotateCamera>();
                app.add_event::<MoveCamera>();
                app.add_systems(Startup, setup);
                app.add_systems(Update, (
                                move_camera.run_if(on_event::<MoveCamera>()),
-                               //pan_camera.run_if(on_event::<PanCamera>()),
-                               //zoom_camera.run_if(on_event::<ZoomCamera>()),
-                               //rotate_camera.run_if(on_event::<RotateCamera>()),
                ));
        }
 }
@@ -45,9 +33,9 @@ fn setup(
 
 fn move_camera(
        mut e_read: EventReader<MoveCamera>,
-       mut camera: Query<(&mut Transform, &mut OrthographicProjection), With<MainCamera>>
+       mut camera: Query<(&Camera, &GlobalTransform, &mut Transform, &mut OrthographicProjection), With<MainCamera>>
 ) {
-       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<PanCamera>,
-//     mut camera: Query<&mut Transform, With<MainCamera>>
-//) {
-//     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<ZoomCamera>,
-//     mut camera: Query<&mut OrthographicProjection, With<MainCamera>>
-//) {
-//     //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<RotateCamera>,
-//     mut camera: Query<&mut Transform, With<MainCamera>>
-//) {
-//     let Ok(mut camera) = camera.get_single_mut() else { return; };
-//     for RotateCamera(th) in e_read.read() {
-//             camera.rotation *= Quat::from_rotation_z(*th);
-//     }
-//}
index 612e8cdb9e271caa7f554c85dbaf83e3938fa2d0..5f148d84fd0299ea6ab97edf12672268c68ae0de 100644 (file)
@@ -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<PrimaryWindow>>,
+       mut scroll_events: EventReader<MouseWheel>,
+       mut e_write: EventWriter<MoveCamera>,
+) {
+       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<ButtonInput<MouseButton>>,
+//     mut motion_events: EventReader<MouseMotion>,
+//     mut e_write: EventWriter<MoveCamera>,
+//) {
+//     for motion in motion_events.read() {
+//
+//     }
+//}
+
 fn handle_camera_input(
        keyboard_input: Res<ButtonInput<KeyCode>>,
        mut e_write: EventWriter<MoveCamera>,
-       //mut e_pan: EventWriter<PanCamera>,
-       //mut e_zoom: EventWriter<ZoomCamera>,
-       //mut e_rotate: EventWriter<RotateCamera>,
 ) {
        let fast = keyboard_input.pressed(KeyCode::ShiftLeft)
                || keyboard_input.pressed(KeyCode::ShiftRight);
index 7670538b0fa82eb1637eb015db2f2681dffc5aed..04560501b23b1940ef29fa1204cb4f6d04eac6f0 100644 (file)
@@ -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::<SelectAt>()
-               .add_event::<Select>()
-               .init_state::<PausedState>()
                .add_plugins(Physics)
+               .configure_sets(Update, PhysicsSet.run_if(in_state(PausedState::Running)))
                .add_plugins(Particles { count: 128 })
                .add_plugins(CameraCfg)
                .add_plugins(Controls)
+               .add_event::<SelectAt>()
+               .add_event::<Select>()
+               .init_state::<PausedState>()
                .add_systems(Startup, setup)
                .add_systems(Update, (
+                               cursor,
                                handle_click,
-                               write_diagnostics,
+                               //write_diagnostics,
                                find_select_particle.run_if(on_event::<SelectAt>()),
                                process_select_particle.run_if(on_event::<Select>())
                                ))
-               .configure_sets(Update, PhysicsSet.run_if(in_state(PausedState::Running)))
                .run();
 }
 
+fn cursor(
+       window: Query<&Window, With<bevy::window::PrimaryWindow>>,
+       //mut head: Query<&mut Transform, With<Head>>,
+       mut query: Query<&mut Text, With<Diagnostics>>,
+       //mut camera: Query<(&Camera, &GlobalTransform, &mut Transform, &mut OrthographicProjection), With<MainCamera>>
+       camera: Query<(&Camera, &GlobalTransform), With<MainCamera>>
+) {
+       //let mut head = head.single_mut();
+       let window = window.single();
+       let (c, g) = camera.single();
+
+       if let Some(p) = window.cursor_position() {//.and_then(|p| c.viewport_to_world_2d(g, p)) {
+               //head.translation = Vec3::from((p, 1.0));
+               for mut output in &mut query {
+                       output.sections[1].value = format!("\t{:?}\n", window.cursor_position());
+                       output.sections[2].value = format!("\t{:?}\n", window.resolution);
+                       output.sections[3].value = format!("\t{:?}\n", window.width());
+                       output.sections[4].value = format!("\t{:?}\n", window.height());
+                       output.sections[5].value = format!("\t{:?}\n", p.x / window.width());
+                       output.sections[6].value = format!("\t{:?}\n", p.y / window.height());
+               }
+       }
+       //head.translation = window.cursor_position().unwrap();
+}
+
 fn setup(
        mut commands: Commands,
 ) {
@@ -115,11 +139,8 @@ fn find_select_particle(
        query: Query<(Entity, &Position)>,
 ) {
        if let Some(SelectAt(p0)) = e_read.read().last() {
-               //info!("Clicking at {:?}", p0);
                for (e, Position(p1)) in &query {
-                       //info!("Attempting at {:?}", p1);
                        if p0.distance(*p1) < 20.0 { // TODO get actual radius
-                               //info!("Selected at {:?}", p1);
                                e_write.send(Select(e));
                        }
                }
@@ -137,14 +158,12 @@ fn process_select_particle(
                        if let Some(_) = s {
                                commands.entity(e).remove::<Selected>();
                                *c = palette.default.clone();
-                               //info!("Deselecting {:?}", e);
                        }
                }
 
                if let Ok((_, _, mut c)) = query.get_mut(*e) {
                        commands.entity(*e).insert(Selected);
                        *c = palette.selected.clone();
-                       //info!("Selecting {:?}", e);
                }
        }
 }
@@ -190,4 +209,3 @@ fn write_diagnostics(
 //     }
 //}
 
-
index 1c0e02f077ae97d8490b6fa993d32f4d0a2d700a..8753ac6d522ac0beb5aebf15b096387dcf23472c 100644 (file)
@@ -9,6 +9,9 @@ use std::f32::consts::PI;
 
 use crate::physics::*;
 
+#[derive(Component)]
+pub struct Head;
+
 #[derive(Resource)]
 pub struct ColorPalette {
        pub default: Handle<ColorMaterial>,
@@ -77,10 +80,10 @@ impl Command for SpawnGroup {
                fn get_vel(u: f32, v: f32) -> Vec2 { Vec2::from_angle(2.0 * PI * u) * v * 5.0 }
                fn get_pos(u: f32, v: f32) -> Vec2 { Vec2::from_angle(2.0 * PI * u) * v.sqrt() * 500.0 }
                let mut i = 0;
+
                while i < self.count {
                        let colors = world.get_resource::<ColorPalette>().unwrap();
                        let meshes = world.get_resource::<MeshPalette>().unwrap();
-
                        world.spawn((
                                        MaterialMesh2dBundle {
                                                mesh: Mesh2dHandle(meshes.standard.clone()),