Changed hitboxed from an 'is a hitbox' to a 'has a hitbox'
authorJustin Worthe <justin@worthe-it.co.za>
Wed, 12 Sep 2018 19:39:34 +0000 (21:39 +0200)
committerJustin Worthe <justin@worthe-it.co.za>
Wed, 12 Sep 2018 19:39:34 +0000 (21:39 +0200)
src/entities/bug.rs
src/entities/home.rs
src/hitbox.rs
src/main.rs

index b5e31c7..b299305 100644 (file)
@@ -26,13 +26,10 @@ impl Bug {
     pub fn advance(&mut self, seconds: f64) {
         self.pos = self.pos + self.velocity * seconds;
     }
-}
 
-impl CircleHitbox for Bug {
-    fn pos(&self) -> Vec2d {
-        self.pos
-    }
-    fn radius(&self) -> f64 {
-        75.
+    pub fn hitbox(&self) -> Hitbox {
+        Hitbox::Circle(CircleHitbox{
+          pos: self.pos, radius: 75.  
+        })
     }
 }
index 5666a75..5e2ea12 100644 (file)
@@ -35,13 +35,10 @@ impl Home {
             SpriteId::Sleepypug2
         } ;
     }
-}
 
-impl CircleHitbox for Home {
-    fn pos(&self) -> Vec2d {
-        self.pos
-    }
-    fn radius(&self) -> f64 {
-        100.
+    pub fn hitbox(&self) -> Hitbox {
+        Hitbox::Circle(CircleHitbox{
+          pos: self.pos, radius: 100.  
+        })
     }
 }
index bd4170e..32f432f 100644 (file)
@@ -1,17 +1,40 @@
 use geometry::*;
 
-pub trait CircleHitbox {
-    fn pos(&self) -> Vec2d;
-    fn radius(&self) -> f64;
-
-    /**
-     * True if the point is inside the hitbox
-     */
-    fn touches_point(&self, point: Vec2d) -> bool {
-        self.pos().distance(point) <= self.radius()
-    }
+pub enum Hitbox {
+    Circle(CircleHitbox),
+    Point(PointHitbox)
+}
+
+pub struct CircleHitbox {
+    pub pos: Vec2d,
+    pub radius: f64
+}
+
+pub struct PointHitbox {
+    pub pos: Vec2d
+}
+
+impl Hitbox {
+    pub fn intersect(a: &Hitbox, b: &Hitbox) -> bool {
+        use self::Hitbox::*;
 
-    fn touches_circle(&self, other: &CircleHitbox) -> bool {
-        self.pos().distance_squared(other.pos()) <= (self.radius() + other.radius()).powi(2)
+        match (a, b) {
+            (Circle(x), Circle(y)) => circles_intersect(x, y),
+            (Circle(x), Point(y)) => circle_point_intersect(x, y),
+            (Point(x), Circle(y)) => circle_point_intersect(y, x),
+            (Point(x), Point(y)) => points_intersect(x, y)
+        }
     }
 }
+
+fn circles_intersect(x: &CircleHitbox, y: &CircleHitbox) -> bool {
+    x.pos.distance_squared(y.pos) <= (x.radius + y.radius).powi(2)
+}
+
+fn circle_point_intersect(x: &CircleHitbox, y: &PointHitbox) -> bool {
+    x.pos.distance_squared(y.pos) <= x.radius.powi(2)
+}
+
+fn points_intersect(x: &PointHitbox, y: &PointHitbox) -> bool {
+    x.pos == y.pos
+}
index 6ed2dbf..16e2836 100644 (file)
@@ -50,7 +50,8 @@ impl App<AssetId> for BugBasherGame {
             self.bugs.retain(|b| b.alive);
             for bug in &mut self.bugs {
                 bug.advance(seconds);
-                if self.home.touches_circle(bug) {
+
+                if Hitbox::intersect(&self.home.hitbox(), &bug.hitbox()) {
                     bug.alive = false;
                     self.lives -= 1;
                 }
@@ -91,10 +92,14 @@ impl App<AssetId> for BugBasherGame {
 
     fn key_down(&mut self, key: KeyCode, ctx: &mut AppContext<AssetId>) {
         let (x, y) = self.camera.invert_translate().apply_f64(ctx.cursor());
+        let cursor_hitbox = Hitbox::Circle(CircleHitbox {
+            pos: Vec2d::new(x, y),
+            radius: 10.
+        });
         match key {
             KeyCode::MouseLeft => {
                 let mut hit = false;
-                for bug in self.bugs.iter_mut().filter(|bug| bug.touches_point(Vec2d::new(x, y))) {
+                for bug in self.bugs.iter_mut().filter(|bug| Hitbox::intersect(&cursor_hitbox, &bug.hitbox())) {
                     if !self.game_over && bug.alive {
                         self.points += 1;
                     }