From 20fd6cec7ea518a98a4f74f746293eb77c170267 Mon Sep 17 00:00:00 2001 From: Alexander Foremny Date: Thu, 14 Mar 2024 16:10:11 +0100 Subject: feat: shooting --- src/client.rs | 44 +++++++++++- src/protocol.rs | 5 ++ src/server.rs | 174 ++++++++++++++++++++++++++++++++++++++++++----- src/shared.rs | 8 ++- src/shared/cooldown.rs | 15 ++++ src/shared/imperative.rs | 3 +- src/shared/projectile.rs | 17 +++++ 7 files changed, 243 insertions(+), 23 deletions(-) create mode 100644 src/shared/cooldown.rs create mode 100644 src/shared/projectile.rs (limited to 'src') diff --git a/src/client.rs b/src/client.rs index bac597e..7dbe7fa 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,7 @@ use crate::client::network::*; use crate::protocol::*; use crate::shared::imperative::*; +use crate::shared::projectile::*; use crate::shared::*; use bevy::input::mouse::MouseButton; use bevy::prelude::*; @@ -27,8 +28,10 @@ impl Plugin for ClientPlugin { transport: self.transport.clone(), }) .add_systems(Startup, setup) - .add_systems(Update, spawn_players) + .add_systems(Update, render_players) + .add_systems(Update, render_projectiles) .add_systems(Update, move_players) + .add_systems(Update, move_projectiles) .add_systems( FixedPreUpdate, buffer_input.in_set(InputSystemSet::BufferInputs), @@ -41,7 +44,7 @@ fn setup(mut client: ClientMut, mut commands: Commands) { client.connect().unwrap(); } -fn spawn_players( +fn render_players( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, @@ -57,6 +60,30 @@ fn spawn_players( } } +fn render_projectiles( + mut commands: Commands, + mut materials: ResMut>, + mut meshes: ResMut>, + projectiles: Query<(Entity, &ProjectilePosition), Added>, +) { + for (entity, position) in projectiles.iter() { + commands.entity(entity).insert(MaterialMesh2dBundle { + mesh: Mesh2dHandle(meshes.add(Circle { radius: 2. })), + material: materials.add(Color::RED), + transform: Transform::from_xyz(position.0.x, position.0.y, 1.), + ..Default::default() + }); + } +} + +fn move_projectiles( + mut projectiles: Query<(&mut Transform, &ProjectilePosition), Changed>, +) { + for (mut transform, projectile_position) in projectiles.iter_mut() { + transform.translation = Vec3::new(projectile_position.0.x, projectile_position.0.y, 0.); + } +} + fn move_players(mut players: Query<(&mut Transform, &PlayerPosition), Changed>) { for (mut transform, player_position) in players.iter_mut() { transform.translation = Vec3::new(player_position.0.x, player_position.0.y, 0.); @@ -64,6 +91,7 @@ fn move_players(mut players: Query<(&mut Transform, &PlayerPosition), Changed, cameras: Query<(&Camera, &GlobalTransform)>, mouse_input: Res>, mut client: ClientMut, @@ -76,7 +104,17 @@ fn buffer_input( if let Some(world_position) = camera.viewport_to_world_2d(camera_transform, cursor_position) { - client.add_input(Inputs::Imperative(Imperative::WalkTo(world_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))); + } } } } diff --git a/src/protocol.rs b/src/protocol.rs index 86d1fa0..7672489 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -1,4 +1,6 @@ +use crate::shared::cooldown::*; use crate::shared::imperative::*; +use crate::shared::projectile::*; use crate::shared::*; use bevy::prelude::*; use lightyear::prelude::*; @@ -26,6 +28,9 @@ pub enum Components { PlayerId(PlayerId), PlayerPosition(PlayerPosition), PlayerColor(PlayerColor), + Projectile(Projectile), + ProjectilePosition(ProjectilePosition), + Cooldown(Cooldown), } #[derive(Channel)] diff --git a/src/server.rs b/src/server.rs index 188aad1..52daf1a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,8 +1,11 @@ use crate::protocol::*; use crate::server::network::*; +use crate::shared::cooldown::*; use crate::shared::imperative::*; +use crate::shared::projectile::*; use crate::shared::*; use bevy::prelude::*; +use bevy::utils::Duration; use bevy::utils::HashMap; use lightyear::prelude::*; use rand::Rng; @@ -29,22 +32,43 @@ impl Plugin for ServerPlugin { .add_plugins(NetworkPlugin { transport: self.transport.clone(), }) - .add_systems(Update, connections) - .add_systems(FixedUpdate, player_input) - .add_systems(Update, imperative); + .add_systems(Startup, setup) + .add_systems(Update, (connects, disconnects)) + .add_systems( + Update, + ( + imperative_attack.after(cooldown_decrement), + imperative_walk_to, + ) + .after(player_input), + ) + .add_systems( + Update, + ( + projectile_move.after(imperative_walk_to), + projectile_despawn, + ) + .chain(), + ) + .add_systems(Update, cooldown_decrement) + .add_systems(FixedUpdate, player_input); } } -fn connections( +fn setup(mut commands: Commands, mut entity_map: ResMut) { + let client_id = 1; + let entity = commands.spawn(PlayerBundle::new(1, Vec2::ZERO, Color::GRAY)); + entity_map.0.insert(client_id, entity.id()); +} + +fn connects( mut commands: Commands, mut connects: EventReader, - mut disconnects: EventReader, mut entity_map: ResMut, ) { let mut rng = rand::thread_rng(); for connection in connects.read() { let client_id = connection.context(); - info!("connected: {:?}", client_id); let position = Vec2::new( 50. * rng.gen_range(-2..=2) as f32, 50. * rng.gen_range(-2..=2) as f32, @@ -53,9 +77,15 @@ fn connections( let entity = commands.spawn(PlayerBundle::new(*client_id, position, color)); entity_map.0.insert(*client_id, entity.id()); } +} + +fn disconnects( + mut commands: Commands, + mut disconnects: EventReader, + mut entity_map: ResMut, +) { for connection in disconnects.read() { let client_id = connection.context(); - info!("disconnected: {:?}", client_id); if let Some(entity_id) = entity_map.0.remove(client_id) { commands.entity(entity_id).despawn(); } @@ -86,22 +116,130 @@ fn player_input( const MOVEMENT_SPEED: f32 = 80.; -fn imperative(mut players: Query<(&mut Imperative, &mut PlayerPosition)>, time: Res