aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-15 03:45:56 +0100
committerLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-15 03:45:56 +0100
commit008477de8b99a16d929912bde73e775a075155ef (patch)
treeeb416eda885c1c188dbc4f96e88cb9871b7de819
parent20fd6cec7ea518a98a4f74f746293eb77c170267 (diff)
feat: hover indicator
-rw-r--r--src/client.rs74
-rw-r--r--src/shared.rs2
2 files changed, 56 insertions, 20 deletions
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<Vec2> {
+ 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)]