mirror of
https://github.com/thilo-behnke/wasm-pong.git
synced 2026-07-11 02:29:25 +00:00
more tests for reflection
This commit is contained in:
@@ -66,4 +66,18 @@ pub mod collision {
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Collision(pub u16, pub u16);
|
||||
|
||||
pub struct CollisionHandler {}
|
||||
|
||||
impl CollisionHandler {
|
||||
pub fn new() -> CollisionHandler {
|
||||
CollisionHandler {}
|
||||
}
|
||||
pub fn handle(&self, obj_a: &mut GameObject, obj_b: &GameObject) {
|
||||
if obj_a.is_static {
|
||||
return;
|
||||
}
|
||||
obj_a.vel.reflect(&obj_b.orientation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::f64::consts::{FRAC_PI_2, FRAC_PI_4};
|
||||
use crate::collision::collision::{Collision, CollisionDetector, CollisionRegistry, Collisions};
|
||||
use crate::collision::collision::{Collision, CollisionDetector, CollisionHandler, CollisionRegistry, Collisions};
|
||||
use crate::game_object::game_object::{GameObject, Shape};
|
||||
use crate::geom::geom::Vector;
|
||||
|
||||
@@ -118,6 +118,7 @@ impl Field {
|
||||
.collect::<Vec<GameObject>>()
|
||||
);
|
||||
let collision_detector = CollisionDetector::new();
|
||||
let collision_handler = CollisionHandler::new();
|
||||
self.collisions = collision_detector.detect_collisions(objs.iter().collect());
|
||||
|
||||
for ball in self.balls.iter_mut() {
|
||||
@@ -132,19 +133,20 @@ impl Field {
|
||||
collision => objs.iter().find(|o| o.id == collision.0).unwrap(),
|
||||
};
|
||||
|
||||
if other.vel == Vector::zero() {
|
||||
let dot = ball.obj.vel.dot(&other.orientation);
|
||||
if dot >= - 0.000001 && dot <= 0.000001 {
|
||||
ball.obj.vel.invert();
|
||||
} else {
|
||||
let angle = ball.obj.vel.angle(&other.orientation);
|
||||
ball.obj.vel.rotate(FRAC_PI_2 - angle);
|
||||
ball.obj.vel.invert();
|
||||
}
|
||||
} else {
|
||||
ball.obj.vel.add(&other.vel);
|
||||
ball.obj.vel.invert();
|
||||
}
|
||||
collision_handler.handle(&mut ball.obj, other);
|
||||
// if other.vel == Vector::zero() {
|
||||
// let dot = ball.obj.vel.dot(&other.orientation);
|
||||
// if dot >= - 0.000001 && dot <= 0.000001 {
|
||||
// ball.obj.vel.invert();
|
||||
// } else {
|
||||
// let angle = ball.obj.vel.angle(&other.orientation);
|
||||
// ball.obj.vel.rotate(FRAC_PI_2 - angle);
|
||||
// ball.obj.vel.invert();
|
||||
// }
|
||||
// } else {
|
||||
// ball.obj.vel.add(&other.vel);
|
||||
// ball.obj.vel.invert();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,12 @@ pub mod geom {
|
||||
(acos_res * 100.0).round() / 100.0
|
||||
}
|
||||
|
||||
pub fn reflect(&mut self, onto: &Vector) {
|
||||
let mut orthogonal = self.get_opposing_orthogonal(onto);
|
||||
orthogonal.scalar_multiplication(2.);
|
||||
self.add(&orthogonal);
|
||||
}
|
||||
|
||||
pub fn get_projection(&self, onto: &Vector) -> Vector {
|
||||
let mut onto_normalized = onto.clone();
|
||||
onto_normalized.normalize();
|
||||
|
||||
49
pong/tests/collision_handler_test.rs
Normal file
49
pong/tests/collision_handler_test.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use rstest::rstest;
|
||||
use pong::collision::collision::CollisionHandler;
|
||||
use pong::game_object::game_object::{GameObject, Shape};
|
||||
use pong::geom::geom::Vector;
|
||||
|
||||
#[rstest]
|
||||
#[case(
|
||||
// given
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(1., 0.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(1., 0.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
// expected
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(1., 0.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(1., 0.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
)]
|
||||
#[case(
|
||||
// given
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(1., 0.), shape: Shape::Rect, shape_params: vec![], is_static: false, orientation: Vector::new(1., 0.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
// expected
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(-1., 0.), shape: Shape::Rect, shape_params: vec![], is_static: false, orientation: Vector::new(1., 0.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
)]
|
||||
#[case(
|
||||
// given
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(-1., 0.), shape: Shape::Rect, shape_params: vec![], is_static: false, orientation: Vector::new(-1., 0.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
// expected
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(1., 0.), shape: Shape::Rect, shape_params: vec![], is_static: false, orientation: Vector::new(-1., 0.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
)]
|
||||
#[case(
|
||||
// given
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(1., 1.), shape: Shape::Rect, shape_params: vec![], is_static: false, orientation: Vector::new(1., 1.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
// expected
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(-1., 1.), shape: Shape::Rect, shape_params: vec![], is_static: false, orientation: Vector::new(1., 1.)},
|
||||
GameObject {id: 1, pos: Vector::zero(), vel: Vector::new(0., 1.), shape: Shape::Rect, shape_params: vec![], is_static: true, orientation: Vector::new(0., 1.)},
|
||||
)]
|
||||
pub fn should_handle_collision(
|
||||
#[case] mut obj_a: GameObject,
|
||||
#[case] obj_b: GameObject,
|
||||
#[case] expected_a: GameObject,
|
||||
#[case] expected_b: GameObject,
|
||||
) {
|
||||
let handler = CollisionHandler {};
|
||||
handler.handle(&mut obj_a, &obj_b);
|
||||
assert_eq!(obj_a, expected_a);
|
||||
assert_eq!(obj_b, expected_b);
|
||||
}
|
||||
@@ -7,29 +7,29 @@ use pong::geom::geom::{Vector};
|
||||
#[case(vec![], vec![])]
|
||||
#[case(
|
||||
vec![
|
||||
GameObject{id: 1, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false},
|
||||
GameObject{id: 2, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false}
|
||||
GameObject{id: 1, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)},
|
||||
GameObject{id: 2, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)}
|
||||
],
|
||||
vec![Collision(1, 2)]
|
||||
)]
|
||||
#[case(
|
||||
vec![
|
||||
GameObject{id: 1, pos: Vector{x: 60., y: 65.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false},
|
||||
GameObject{id: 2, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false}
|
||||
GameObject{id: 1, pos: Vector{x: 60., y: 65.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)},
|
||||
GameObject{id: 2, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)}
|
||||
],
|
||||
vec![Collision(1, 2)]
|
||||
)]
|
||||
#[case(
|
||||
vec![
|
||||
GameObject{id: 1, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false},
|
||||
GameObject{id: 2, pos: Vector{x: 80., y: 80.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false}
|
||||
GameObject{id: 1, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)},
|
||||
GameObject{id: 2, pos: Vector{x: 80., y: 80.}, shape: Shape::Rect, shape_params: vec![20, 20], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)}
|
||||
],
|
||||
vec![]
|
||||
)]
|
||||
#[case(
|
||||
vec![
|
||||
GameObject{id: 1, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![50, 50], vel: Vector::zero(), is_static: false},
|
||||
GameObject{id: 2, pos: Vector{x: 500., y: 50.}, shape: Shape::Rect, shape_params: vec![50, 50], vel: Vector::zero(), is_static: false}
|
||||
GameObject{id: 1, pos: Vector{x: 50., y: 50.}, shape: Shape::Rect, shape_params: vec![50, 50], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)},
|
||||
GameObject{id: 2, pos: Vector{x: 500., y: 50.}, shape: Shape::Rect, shape_params: vec![50, 50], vel: Vector::zero(), is_static: false, orientation: Vector::new(1., 1.)}
|
||||
],
|
||||
vec![]
|
||||
)]
|
||||
|
||||
@@ -12,6 +12,7 @@ pub fn should_update_pos(#[case] start_pos: Vector, #[case] vel: Vector, #[case]
|
||||
shape: Shape::Rect,
|
||||
shape_params: vec![],
|
||||
is_static: false,
|
||||
orientation: Vector::new(1., 0.)
|
||||
};
|
||||
obj.update_pos();
|
||||
assert_eq!(obj.pos, expected_pos);
|
||||
|
||||
@@ -121,4 +121,17 @@ pub fn should_get_opposing_orthogonal(
|
||||
assert_eq!(orthogonal, expected);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(Vector::new(1., 1.), Vector::new(1., 0.), Vector::new(1., -1.))]
|
||||
#[case(Vector::new(-1., 1.), Vector::new(1., 0.), Vector::new(-1., -1.))]
|
||||
#[case(Vector::new(1., -1.), Vector::new(0., 1.), Vector::new(-1., -1.))]
|
||||
#[case(Vector::new(-1., -1.), Vector::new(0., 1.), Vector::new(1., -1.))]
|
||||
pub fn should_reflect_vector(
|
||||
#[case] mut vector: Vector,
|
||||
#[case] onto: Vector,
|
||||
#[case] expected: Vector,
|
||||
) {
|
||||
vector.reflect(&onto);
|
||||
assert_eq!(vector, expected);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user