diff --git a/src/main.rs b/src/main.rs index affe33d..3de7531 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,27 +9,33 @@ fn main() { fps_counter::FpsCounterPlugin, MeshPickingPlugin, )) - .add_systems(Startup, setup) - .add_systems(Startup, change_window_mode) - // .add_systems(Update, switch_focused_shape) + .add_systems(Startup, (setup_camera, change_window_mode)) + .add_systems(Startup, setup_shapes) .add_systems(Update, show_focused_shape) .add_systems(FixedUpdate, focused_follow_cursor) .add_systems(Update, draw_cursor) .run(); } +const CURSOR_SIZE: f32 = 10.0; +const FOCUS_MARK_SIZE: f32 = 10.0; +const SHAPE_Z_POS: f32 = 0.0; +const SHAPE_FOLLOW_SPEED: f32 = 100.0; fn change_window_mode(mut windows: Query<&mut Window>) { let mut window = windows.single_mut(); // window.mode = WindowMode::Fullscreen(MonitorSelection::Current); window.present_mode = bevy::window::PresentMode::AutoNoVsync; } -fn setup( + +fn setup_camera(mut commands: Commands) { + commands.spawn(Camera2d); +} + +fn setup_shapes( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { - commands.spawn(Camera2d); - let shapes = [ meshes.add(Rectangle::new(50.0, 100.0)), meshes.add(Rectangle::new(100.0, 50.0)), @@ -41,48 +47,57 @@ fn setup( Mesh2d(shape), MeshMaterial2d(materials.add(Color::from(RED))), Focused(true), - Transform::from_xyz((i as f32 - num_shapes as f32 / 2.0) * 150.0, 0.0, 0.0), + Transform::from_xyz( + (i as f32 - num_shapes as f32 / 2.0) * 150.0, + 0.0, + SHAPE_Z_POS, + ), )) .observe(on_click_shape); } } + +fn on_click_shape(click: Trigger>, mut focused: Query<&mut Focused>) { + let Ok(mut focused) = focused.get_mut(click.entity()) else { + return; + }; + + focused.0 = !focused.0; +} + fn draw_cursor( camera_query: Single<(&Camera, &GlobalTransform)>, windows: Query<&Window>, mut gizmos: Gizmos, ) { - let Some(point) = get_cursor_worl_pos(camera_query, windows) else { + let Some(point) = get_cursor_world_pos(camera_query, windows) else { return; }; - gizmos.circle_2d(point, 10.0, WHITE); + gizmos.circle_2d(point, CURSOR_SIZE, WHITE); } -fn get_cursor_worl_pos( +fn get_cursor_world_pos( camera_query: Single<(&Camera, &GlobalTransform)>, windows: Query<&Window>, ) -> Option { let (camera, camera_transform) = *camera_query; - let Ok(window) = windows.get_single() else { - return None; - }; - let Some(cursor_position) = window.cursor_position() else { - return None; - }; + let cursor_position = windows.get_single().ok()?.cursor_position()?; - let Ok(point) = camera.viewport_to_world_2d(camera_transform, cursor_position) else { - return None; - }; + let point = camera + .viewport_to_world_2d(camera_transform, cursor_position) + .ok()?; Some(point) } #[derive(Component)] struct Focused(bool); + fn show_focused_shape(focused: Query<(&Focused, &GlobalTransform)>, mut gizmos: Gizmos) { for (focused, transform) in focused.iter() { let point: Vec2 = transform.translation().xy(); if focused.0 { - gizmos.circle_2d(point, 10.0, WHITE); + gizmos.circle_2d(point, FOCUS_MARK_SIZE, WHITE); } } } @@ -92,29 +107,29 @@ fn focused_follow_cursor( camera_query: Single<(&Camera, &GlobalTransform)>, windows: Query<&Window>, ) { - let Some(point) = get_cursor_worl_pos(camera_query, windows) else { + let Some(point) = get_cursor_world_pos(camera_query, windows) else { return; }; - const MOVEMENT_SPEED: f32 = 100.0; for (focused, mut transform) in focused.iter_mut() { if focused.0 { - let move_vec = point - transform.translation.xy(); - if move_vec.length_squared() < 0.0001 { - continue; - } - let capped_move_vec = move_vec.normalize() * time.delta_secs() * MOVEMENT_SPEED; - if capped_move_vec.length_squared() > move_vec.length_squared() { - transform.translation += move_vec.extend(0.0); - continue; - } - transform.translation += capped_move_vec.extend(0.0); + move_towards( + point, + &mut transform, + time.delta_secs() * SHAPE_FOLLOW_SPEED, + ); } } } -fn on_click_shape(click: Trigger>, mut focused: Query<&mut Focused>) { - let Ok(mut focused) = focused.get_mut(click.entity()) else { - return; - }; - focused.0 = !focused.0; +fn move_towards(point: Vec2, transform: &mut Mut, speed_per_frame: f32) { + let move_vec = point - transform.translation.xy(); + if move_vec.length_squared() < 0.0001 { + return; + } + let capped_move_vec = move_vec.normalize() * speed_per_frame; + if capped_move_vec.length_squared() > move_vec.length_squared() { + // prevent overshooting if we are already close to the target + transform.translation += move_vec.extend(SHAPE_Z_POS); + } + transform.translation += capped_move_vec.extend(SHAPE_Z_POS); }