From 58706af0c514d5eb9d0ffb9f478e16ba3acd575a Mon Sep 17 00:00:00 2001 From: Ian Tayler Date: Wed, 18 Nov 2020 14:51:23 -0300 Subject: [PATCH] Implement reduction of player collision boxes with ball. When the ball is going fast and the player is not a goalie. --- assets/sprites/player.ron | 3 ++- src/components/collision_box.rs | 2 +- src/components/player.rs | 23 ++++++++++++++++++++++- src/config.rs | 5 +++++ src/systems/collision.rs | 16 ++++++++++++---- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/assets/sprites/player.ron b/assets/sprites/player.ron index 036b1a3..f1a08ff 100644 --- a/assets/sprites/player.ron +++ b/assets/sprites/player.ron @@ -128,7 +128,8 @@ Prefab( push_strength: 96.0, side: UpperSide, ), - robot: Robot(logic_module: EngineRunner("basic")), + human: Human, + // robot: Robot(logic_module: EngineRunner("basic")), ), ), ), diff --git a/src/components/collision_box.rs b/src/components/collision_box.rs index b0f481e..a80a961 100644 --- a/src/components/collision_box.rs +++ b/src/components/collision_box.rs @@ -8,7 +8,7 @@ use amethyst::{ }; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Clone, Serialize, PrefabData)] +#[derive(Debug, Deserialize, Copy, Clone, Serialize, PrefabData)] #[prefab(Component)] pub struct CollisionBox { /// Distance from the center to the upper left. diff --git a/src/components/player.rs b/src/components/player.rs index 5c0d0d6..d8ee551 100644 --- a/src/components/player.rs +++ b/src/components/player.rs @@ -1,4 +1,4 @@ -use crate::{config, utils}; +use crate::{components::CollisionBox, config, utils}; use amethyst::{ assets::PrefabData, derive::PrefabData, @@ -72,3 +72,24 @@ impl PlayerType { impl Component for PlayerType { type Storage = DenseVecStorage; } + +/// Makes balls that go fast collide less with players. +pub fn reduce_collision( + player_collision: &CollisionBox, + player_type: &PlayerType, + ball_speed: f32, +) -> CollisionBox { + match player_type { + PlayerType::Goalie => *player_collision, + _ => { + let max_speed = config::BALL_SPEED_FOR_MINIMUM_COLLISION; + let min_factor = config::BALL_MINIMUM_COLLISION_FACTOR; + let reduce_factor = ball_speed.min(max_speed) * (1.0 - min_factor) / max_speed; + let keep_factor = 1.0 - reduce_factor; + CollisionBox { + upper_left_distance: player_collision.upper_left_distance * keep_factor, + lower_right_distance: player_collision.lower_right_distance * keep_factor, + } + } + } +} diff --git a/src/config.rs b/src/config.rs index 8976e47..cbb5717 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,11 @@ // TODO: move this to configuration files? +// Screen constants pub const SCREEN_WIDTH: f32 = 256.0; pub const SCREEN_HEIGHT: f32 = 256.0; +// Some ~physics constants +pub const BALL_SPEED_FOR_MINIMUM_COLLISION: f32 = 256.0; +pub const BALL_MINIMUM_COLLISION_FACTOR: f32 = 0.3; +// Player position constants pub const MAXIMUM_TEAM_SIZE: usize = 5; pub const FORWARD_NUMBER: usize = 0; pub const GOALIE_NUMBER: usize = 1; diff --git a/src/systems/collision.rs b/src/systems/collision.rs index 618c8eb..8198216 100644 --- a/src/systems/collision.rs +++ b/src/systems/collision.rs @@ -1,5 +1,7 @@ use crate::{ - components::{collision_box, Ball, CollisionBox, MovementState, Net, Player}, + components::{ + collision_box, player, Ball, CollisionBox, MovementState, Net, Player, PlayerType, + }, resources::Score, utils::Side, }; @@ -18,6 +20,7 @@ impl<'s> System<'s> for Collisions { WriteStorage<'s, MovementState>, ReadStorage<'s, Ball>, ReadStorage<'s, Player>, + ReadStorage<'s, PlayerType>, ReadStorage<'s, Net>, ReadStorage<'s, CollisionBox>, ReadStorage<'s, Transform>, @@ -32,6 +35,7 @@ impl<'s> System<'s> for Collisions { mut movement_states, balls, players, + player_types, nets, collision_boxes, transforms, @@ -46,13 +50,17 @@ impl<'s> System<'s> for Collisions { (&mut movement_states, &balls, &collision_boxes, &transforms).join() { // Handle collisions with players (i.e. kicks) - for (player, player_collision, player_transform) in - (&players, &collision_boxes, &transforms).join() + for (player, player_type, player_collision, player_transform) in + (&players, &player_types, &collision_boxes, &transforms).join() { if collision_box::are_colliding( ball_collision, ball_transform, - player_collision, + &player::reduce_collision( + player_collision, + player_type, + movement_state.velocity.norm(), + ), player_transform, ) { let center_difference =