From 008477de8b99a16d929912bde73e775a075155ef Mon Sep 17 00:00:00 2001 From: Alexander Foremny Date: Fri, 15 Mar 2024 03:45:56 +0100 Subject: feat: hover indicator --- src/client.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++--------------- src/shared.rs | 2 +- 2 files changed, 56 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client.rs b/src/client.rs index 7dbe7fa..96baeb8 100644 --- a/src/client.rs +++ b/src/client.rs @@ -11,6 +11,10 @@ use lightyear::prelude::*; mod network; +const PLAYER_RADIUS: f32 = 10.; +const PLAYER_HOVER_INDICATOR_RADIUS: f32 = 13.; +const PLAYER_HOVER_RADIUS: f32 = 20.; + pub fn main(transport: TransportConfig) { App::new() .add_plugins(DefaultPlugins) @@ -35,7 +39,8 @@ impl Plugin for ClientPlugin { .add_systems( FixedPreUpdate, buffer_input.in_set(InputSystemSet::BufferInputs), - ); + ) + .add_systems(Last, gizmos_hover_indicator); } } @@ -52,7 +57,9 @@ fn render_players( ) { for (entity, position, color) in players.iter() { commands.entity(entity).insert(MaterialMesh2dBundle { - mesh: Mesh2dHandle(meshes.add(Circle { radius: 10. })), + mesh: Mesh2dHandle(meshes.add(Circle { + radius: PLAYER_RADIUS, + })), material: materials.add(color.0), transform: Transform::from_xyz(position.0.x, position.0.y, 0.), ..Default::default() @@ -97,25 +104,54 @@ fn buffer_input( mut client: ClientMut, windows: Query<&Window>, ) { - let window = windows.single(); - let (camera, camera_transform) = cameras.single(); if mouse_input.just_pressed(MouseButton::Left) { - if let Some(cursor_position) = window.cursor_position() { - if let Some(world_position) = - camera.viewport_to_world_2d(camera_transform, cursor_position) - { - let mut attackable_player = None; - for (player, position) in attackables.iter() { - if position.0.distance(world_position) < 20. { - attackable_player = Some(player); - } - } - if let Some(target_player) = attackable_player { - client.add_input(Inputs::Imperative(Imperative::Attack(*target_player))); - } else { - client.add_input(Inputs::Imperative(Imperative::WalkTo(world_position))); - } + if let Some((target_player, _)) = hovered_player(&windows, &cameras, &attackables) { + client.add_input(Inputs::Imperative(Imperative::Attack(target_player))); + } else { + if let Some(world_position) = cursor_world_position(&windows, &cameras) { + client.add_input(Inputs::Imperative(Imperative::WalkTo(world_position))); } } } } + +fn gizmos_hover_indicator( + mut gizmos: Gizmos, + hoverables: Query<(&PlayerId, &PlayerPosition)>, + cameras: Query<(&Camera, &GlobalTransform)>, + windows: Query<&Window>, +) { + let Some((_, position)) = hovered_player(&windows, &cameras, &hoverables) else { + return; + }; + gizmos.circle_2d(position.0, PLAYER_HOVER_INDICATOR_RADIUS, Color::GREEN); +} + +fn cursor_world_position( + windows: &Query<&Window>, + cameras: &Query<(&Camera, &GlobalTransform)>, +) -> Option { + let window = windows.single(); + let (camera, camera_transform) = cameras.single(); + let Some(cursor_position) = window.cursor_position() else { + return None; + }; + camera.viewport_to_world_2d(camera_transform, cursor_position) +} + +fn hovered_player( + windows: &Query<&Window>, + cameras: &Query<(&Camera, &GlobalTransform)>, + hoverables: &Query<(&PlayerId, &PlayerPosition)>, +) -> Option<(PlayerId, PlayerPosition)> { + let Some(world_position) = cursor_world_position(&windows, &cameras) else { + return None; + }; + let mut hovered_player = None; + for (id, position) in hoverables.iter() { + if position.0.distance(world_position) < PLAYER_HOVER_RADIUS { + hovered_player = Some((*id, *position)); + } + } + hovered_player +} diff --git a/src/shared.rs b/src/shared.rs index 146e343..4db5224 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -31,7 +31,7 @@ pub struct PlayerBundle { #[derive(Component, Message, Serialize, Deserialize, Clone, Copy, Debug, PartialEq)] pub struct PlayerId(pub ClientId); -#[derive(Component, Message, Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Component, Message, Serialize, Deserialize, Clone, Copy, Debug, PartialEq)] pub struct PlayerPosition(pub Vec2); #[derive(Component, Message, Serialize, Deserialize, Clone, Debug, PartialEq)] -- cgit v1.2.3