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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! This crate serves the purpose of being an extremely simple collision library.
//! Only features AABB collision for now. For how to use, see example below. Basically,
//! all you need to do is implement the `Object` trait for all your structs that you want to have
//! collision. From the `Object` trait you need to implement the `fn boundary(&self) -> Boundary`
//! function. Then your structs will have the 
//! `fn does_collide(&self, objects: &[Box<dyn Object>]) -> bool` function included.

//! ```rust
//! use basic_collision::*;
//! 
//! #[derive(Debug)]
//! pub struct Block {
//!     x: f32,
//!     y: f32,
//!     width: f32,
//!     height: f32,
//! }
//! 
//! impl Block {
//!     pub fn new(x: f32, y: f32, width: f32, height: f32) -> Block {
//!         Block {
//!             x, y, width, height
//!         }
//!     }
//! }
//! 
//! impl Object for Block {
//!     fn boundary(&self) -> Boundary {
//!         Boundary::new(self.x, self.y, self.width, self.height)
//!     }
//! }
//! 
//! fn main() {
//!     let blocks: Vec<Box<dyn Object>> = vec![
//!         Box::new(Block::new(100., 150., 60., 50.)),
//!         Box::new(Block::new(150., 150., 40., 50.)),
//!         Box::new(Block::new(200., 150., 60., 50.)),
//!     ];
//!     for block in blocks.iter() {
//!         if block.does_collide(&blocks[..]) {
//!             println!("Collision occurred!");
//!         }
//!     }
//! }
//! ```

pub trait Object {
    fn boundary(&self) -> Boundary;
    fn does_collide(&self, objects: &[Box<dyn Object>]) -> bool {
        for object in objects.iter() {
            let this = self.boundary();
            let other = object.boundary();
            if this.collides(&other) && this.is_duplicate(&other) == false {
                return true;
            }
        }
        false
    }
}

#[derive(Debug, Copy, Clone)]
pub struct Boundary {
    x: f32,
    y: f32,
    width: f32,
    height: f32,
}

impl Boundary {
    pub fn new(x: f32, y: f32, width: f32, height: f32) -> Boundary {
        Boundary {
            x,
            y,
            width,
            height,
        }
    }
    pub fn collides(&self, other: &Boundary) -> bool {
        if self.x < other.x + other.width
            && self.x + self.width > other.x
            && self.y < other.y + other.height
            && self.y + self.height > other.y
        {
            return true;
        }
        false
    }
    pub fn is_duplicate(&self, other: &Boundary) -> bool {
        self.x == other.x
            && self.y == other.y
            && self.width == other.width
            && self.height == other.height
    }
}