basic_collision/lib.rs
1//! This crate serves the purpose of being an extremely simple collision library.
2//! Only features AABB collision for now. For how to use, see example below. Basically,
3//! all you need to do is implement the `Object` trait for all your structs that you want to have
4//! collision. From the `Object` trait you need to implement the `fn boundary(&self) -> Boundary`
5//! function. Then your structs will have the
6//! `fn does_collide(&self, objects: &[Box<dyn Object>]) -> bool` function included.
7
8//! ```rust
9//! use basic_collision::*;
10//!
11//! #[derive(Debug)]
12//! pub struct Block {
13//! x: f32,
14//! y: f32,
15//! width: f32,
16//! height: f32,
17//! }
18//!
19//! impl Block {
20//! pub fn new(x: f32, y: f32, width: f32, height: f32) -> Block {
21//! Block {
22//! x, y, width, height
23//! }
24//! }
25//! }
26//!
27//! impl Object for Block {
28//! fn boundary(&self) -> Boundary {
29//! Boundary::new(self.x, self.y, self.width, self.height)
30//! }
31//! }
32//!
33//! fn main() {
34//! let blocks: Vec<Box<dyn Object>> = vec![
35//! Box::new(Block::new(100., 150., 60., 50.)),
36//! Box::new(Block::new(150., 150., 40., 50.)),
37//! Box::new(Block::new(200., 150., 60., 50.)),
38//! ];
39//! for block in blocks.iter() {
40//! if block.does_collide(&blocks[..]) {
41//! println!("Collision occurred!");
42//! }
43//! }
44//! }
45//! ```
46
47pub trait Object {
48 fn boundary(&self) -> Boundary;
49 fn does_collide(&self, objects: &[Box<dyn Object>]) -> bool {
50 for object in objects.iter() {
51 let this = self.boundary();
52 let other = object.boundary();
53 if this.collides(&other) && this.is_duplicate(&other) == false {
54 return true;
55 }
56 }
57 false
58 }
59}
60
61#[derive(Debug, Copy, Clone)]
62pub struct Boundary {
63 x: f32,
64 y: f32,
65 width: f32,
66 height: f32,
67}
68
69impl Boundary {
70 pub fn new(x: f32, y: f32, width: f32, height: f32) -> Boundary {
71 Boundary {
72 x,
73 y,
74 width,
75 height,
76 }
77 }
78 pub fn collides(&self, other: &Boundary) -> bool {
79 if self.x < other.x + other.width
80 && self.x + self.width > other.x
81 && self.y < other.y + other.height
82 && self.y + self.height > other.y
83 {
84 return true;
85 }
86 false
87 }
88 pub fn is_duplicate(&self, other: &Boundary) -> bool {
89 self.x == other.x
90 && self.y == other.y
91 && self.width == other.width
92 && self.height == other.height
93 }
94}