use float in vector - breaks movement of objects

This commit is contained in:
Thilo Behnke
2022-04-20 23:35:27 +02:00
parent cae1886684
commit 9870e719da
5 changed files with 63 additions and 36 deletions

View File

@@ -68,23 +68,23 @@ impl Field {
pub fn tick(&mut self, inputs: Vec<Input>) {
for ball in self.balls.iter_mut() {
if ball.obj.vel == Vector::zero() {
ball.obj.set_vel_x(-1)
ball.obj.set_vel_x(-1.)
}
}
for player in self.players.iter_mut() {
let input_opt = inputs.iter().find(|input| player.obj.id == input.obj_id);
if let None = input_opt {
player.obj.set_vel_y(0);
player.obj.set_vel_y(0.);
continue;
}
let input = input_opt.unwrap();
match input.input {
InputType::UP => {
player.obj.vel.y = min(player.obj.vel.y + 1, 5);
player.obj.vel.y = (player.obj.vel.y + 1.).min(5.);
}
InputType::DOWN => {
player.obj.vel.y = max(player.obj.vel.y - 1, -5);
player.obj.vel.y = (player.obj.vel.y - 1.).max(-5.);
}
};
}

View File

@@ -22,22 +22,15 @@ pub mod game_object {
pub fn update_pos(&mut self, field_width: u16, field_height: u16) {
let updated_x = self.x.wrapping_add(self.vel.x as u16);
let updated_y = self.y.wrapping_add(self.vel.y as u16);
// let updated_bounding_box = self.bounding_box_from(updated_x, updated_y);
// if updated_bounding_box.points().iter().any(|p| {
// p.x < 0 || p.x > field_width as i16 || p.y < 0 || p.y > field_height as i16
// }) {
// return;
// }
self.x = updated_x;
self.y = updated_y;
}
pub fn set_vel_x(&mut self, x: i32) {
pub fn set_vel_x(&mut self, x: f64) {
self.vel.x = x
}
pub fn set_vel_y(&mut self, y: i32) {
pub fn set_vel_y(&mut self, y: f64) {
self.vel.y = y
}

View File

@@ -1,17 +1,23 @@
pub mod geom {
#[derive(Debug, Clone, PartialEq)]
pub struct Vector {
pub x: i32,
pub y: i32,
pub x: f64,
pub y: f64,
}
impl Vector {
pub fn zero() -> Vector {
Vector { x: 0, y: 0 }
Vector { x: 0., y: 0. }
}
pub fn unit() -> Vector {
Vector { x: 1, y: 1 }
Vector { x: 1., y: 1. }
}
pub fn new(x: f64, y: f64) -> Vector {
Vector {
x, y
}
}
pub fn normalize(&mut self) {
@@ -26,13 +32,29 @@ pub mod geom {
}
pub fn invert(&mut self) {
self.x = self.x * -1;
self.y = self.y * -1;
self.x = self.x * -1.;
self.y = self.y * -1.;
}
pub fn len(&self) -> i32 {
let distance = self.x.pow(2) + self.y.pow(2);
return (distance as f32).sqrt() as i32;
pub fn dot(&self, other: &Vector) -> f64 {
return self.x * other.x + self.y * other.y
}
pub fn angle(&self, other: &Vector) -> f64 {
let mut self_clone = self.clone();
self_clone.normalize();
let mut other_clone = other.clone();
other_clone.normalize();
let dot = self_clone.dot(&other_clone);
let dot_float = dot as f64;
let acos_res = dot_float.acos();
(acos_res * 100.0).round() / 100.0
}
pub fn len(&self) -> f64 {
let distance = self.x.powi(2) + self.y.powi(2);
return (distance as f64).sqrt();
}
}

View File

@@ -36,7 +36,7 @@ mod game_field_tests {
fn player_input_update_out_of_bounds__up() {
let height = 1000;
let mut field = Field::mock(1000, height);
field.add_player(1, 50, height - 6);
field.add_player(1, 50, height - height / 5 / 2);
let inputs = vec![Input {
input: InputType::UP,
obj_id: 1,
@@ -44,7 +44,7 @@ mod game_field_tests {
field.tick(inputs);
let players = field.players();
let player = players.first().unwrap();
assert_eq!(player.obj.y, height - 6);
assert_eq!(player.obj.y, height - height / 5 / 2);
}
#[test]
@@ -59,6 +59,6 @@ mod game_field_tests {
field.tick(inputs);
let players = field.players();
let player = players.first().unwrap();
assert_eq!(player.obj.y, height / 5);
assert_eq!(player.obj.y, height / 5 / 2);
}
}

View File

@@ -2,24 +2,24 @@ use rstest::rstest;
use pong::geom::geom::Vector;
#[rstest]
#[case(1, 0, 1)]
#[case(0, 1, 1)]
#[case(3, 4, 5)]
pub fn should_get_correct_length(#[case] x: i32, #[case] y: i32, #[case] expected: i32) {
#[case(1., 0., 1.)]
#[case(0., 1., 1.)]
#[case(3., 4., 5.)]
pub fn should_get_correct_length(#[case] x: f64, #[case] y: f64, #[case] expected: f64) {
let vector = Vector { x, y };
let len = vector.len();
assert_eq!(len, expected);
}
#[rstest]
#[case(1, 0, 1, 0)]
#[case(3, 0, 1, 0)]
#[case(3, 4, 3 / 5, 4 / 5)]
#[case(1., 0., 1., 0.)]
#[case(3., 0., 1., 0.)]
#[case(3., 4., 3. / 5., 4. / 5.)]
pub fn should_normalize_correctly(
#[case] x: i32,
#[case] y: i32,
#[case] expected_x: i32,
#[case] expected_y: i32,
#[case] x: f64,
#[case] y: f64,
#[case] expected_x: f64,
#[case] expected_y: f64,
) {
let mut vector = Vector { x, y };
let expected = Vector {
@@ -29,3 +29,15 @@ pub fn should_normalize_correctly(
vector.normalize();
assert_eq!(vector, expected);
}
#[rstest]
#[case(Vector::new(1., 1.), Vector::new(2., 2.), 0.)]
#[case(Vector::new(1., 0.), Vector::new(1., 1.), 0.79)]
pub fn should_calculate_angle_correctly(
#[case] vector_a: Vector,
#[case] vector_b: Vector,
#[case] expected_angle: f64
) {
let res = vector_a.angle(&vector_b);
assert_eq!(res, expected_angle);
}