This commit is contained in:
OMGeeky
2025-04-13 16:35:35 +02:00
parent 68c6bec9dd
commit 17f177c727

View File

@@ -9,27 +9,33 @@ fn main() {
fps_counter::FpsCounterPlugin, fps_counter::FpsCounterPlugin,
MeshPickingPlugin, MeshPickingPlugin,
)) ))
.add_systems(Startup, setup) .add_systems(Startup, (setup_camera, change_window_mode))
.add_systems(Startup, change_window_mode) .add_systems(Startup, setup_shapes)
// .add_systems(Update, switch_focused_shape)
.add_systems(Update, show_focused_shape) .add_systems(Update, show_focused_shape)
.add_systems(FixedUpdate, focused_follow_cursor) .add_systems(FixedUpdate, focused_follow_cursor)
.add_systems(Update, draw_cursor) .add_systems(Update, draw_cursor)
.run(); .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>) { fn change_window_mode(mut windows: Query<&mut Window>) {
let mut window = windows.single_mut(); let mut window = windows.single_mut();
// window.mode = WindowMode::Fullscreen(MonitorSelection::Current); // window.mode = WindowMode::Fullscreen(MonitorSelection::Current);
window.present_mode = bevy::window::PresentMode::AutoNoVsync; 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 commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>, mut materials: ResMut<Assets<ColorMaterial>>,
) { ) {
commands.spawn(Camera2d);
let shapes = [ let shapes = [
meshes.add(Rectangle::new(50.0, 100.0)), meshes.add(Rectangle::new(50.0, 100.0)),
meshes.add(Rectangle::new(100.0, 50.0)), meshes.add(Rectangle::new(100.0, 50.0)),
@@ -41,48 +47,57 @@ fn setup(
Mesh2d(shape), Mesh2d(shape),
MeshMaterial2d(materials.add(Color::from(RED))), MeshMaterial2d(materials.add(Color::from(RED))),
Focused(true), 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); .observe(on_click_shape);
} }
} }
fn on_click_shape(click: Trigger<Pointer<Click>>, mut focused: Query<&mut Focused>) {
let Ok(mut focused) = focused.get_mut(click.entity()) else {
return;
};
focused.0 = !focused.0;
}
fn draw_cursor( fn draw_cursor(
camera_query: Single<(&Camera, &GlobalTransform)>, camera_query: Single<(&Camera, &GlobalTransform)>,
windows: Query<&Window>, windows: Query<&Window>,
mut gizmos: Gizmos, 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; 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)>, camera_query: Single<(&Camera, &GlobalTransform)>,
windows: Query<&Window>, windows: Query<&Window>,
) -> Option<Vec2> { ) -> Option<Vec2> {
let (camera, camera_transform) = *camera_query; let (camera, camera_transform) = *camera_query;
let Ok(window) = windows.get_single() else { let cursor_position = windows.get_single().ok()?.cursor_position()?;
return None;
};
let Some(cursor_position) = window.cursor_position() else {
return None;
};
let Ok(point) = camera.viewport_to_world_2d(camera_transform, cursor_position) else { let point = camera
return None; .viewport_to_world_2d(camera_transform, cursor_position)
}; .ok()?;
Some(point) Some(point)
} }
#[derive(Component)] #[derive(Component)]
struct Focused(bool); struct Focused(bool);
fn show_focused_shape(focused: Query<(&Focused, &GlobalTransform)>, mut gizmos: Gizmos) { fn show_focused_shape(focused: Query<(&Focused, &GlobalTransform)>, mut gizmos: Gizmos) {
for (focused, transform) in focused.iter() { for (focused, transform) in focused.iter() {
let point: Vec2 = transform.translation().xy(); let point: Vec2 = transform.translation().xy();
if focused.0 { 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)>, camera_query: Single<(&Camera, &GlobalTransform)>,
windows: Query<&Window>, 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; return;
}; };
const MOVEMENT_SPEED: f32 = 100.0;
for (focused, mut transform) in focused.iter_mut() { for (focused, mut transform) in focused.iter_mut() {
if focused.0 { if focused.0 {
let move_vec = point - transform.translation.xy(); move_towards(
if move_vec.length_squared() < 0.0001 { point,
continue; &mut transform,
} time.delta_secs() * SHAPE_FOLLOW_SPEED,
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);
} }
} }
} }
fn on_click_shape(click: Trigger<Pointer<Click>>, 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<Transform>, 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);
} }