blob: 458f1e7ca2d7fa6309b506666fe3a200b8d29810 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
pub(crate) use error::{Error, Result};
pub use point::Point;
pub use vector::Vector;
mod error;
mod point;
mod vector;
pub trait Physics {
fn tick_time<E: crate::Engine>(&mut self, engine: E) -> Result<()>;
}
pub trait Position {
fn get_position(&self) -> Point;
fn set_position<P: Into<Point>>(&mut self, position: P) -> Result<()>;
}
pub trait Velocity: Position {
fn get_velocity(&self) -> Vector;
fn set_velocity<V: Into<Vector>>(&mut self, velocity: V) -> Result<()>;
fn apply_velocity(&mut self) -> Result<()> {
self.set_position(self.get_position() + self.get_velocity())
}
fn reset_velocity(&mut self) -> Result<()> {
self.set_velocity(Vector::default())
}
}
pub trait Collider {
fn collision_map(&self) -> &Vec<Point>;
}
pub trait Collidable: Collider + Velocity {
fn next_collision_map(&self) -> Vec<Point> {
let velocity = self.get_velocity();
self.collision_map().iter().map(|p| *p + velocity).collect()
}
fn check_collision<C: Collider>(&self, colliders: C) -> Result<()> {
let collision = self
.next_collision_map()
.iter()
.zip(colliders.collision_map())
.filter_map(|(p1, p2)| p1.eq(p2).then_some(*p1))
.collect::<Vec<point::Point>>();
if !collision.is_empty() {
Ok(())
} else {
Err(Error::Collision(collision))
}
}
fn check_colliders<C: Collider>(&self, colliders: Vec<C>) -> Result<()> {
for collidable in colliders {
self.check_collision(collidable)?
}
Ok(())
}
}
impl<T: Velocity + Collidable> Physics for T {
fn tick_time<E: crate::Engine>(&mut self, engine: E) -> Result<()> {
self.check_colliders(engine.get_colliders())?;
self.apply_velocity()
}
}
|