From 38caea2a14bb3c205e4c42daa9f11f0f60550360 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 12 Sep 2018 21:39:34 +0200 Subject: Changed hitboxed from an 'is a hitbox' to a 'has a hitbox' --- src/entities/bug.rs | 11 ++++------- src/entities/home.rs | 11 ++++------- src/hitbox.rs | 47 +++++++++++++++++++++++++++++++++++------------ src/main.rs | 9 +++++++-- 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/entities/bug.rs b/src/entities/bug.rs index b5e31c7..b299305 100644 --- a/src/entities/bug.rs +++ b/src/entities/bug.rs @@ -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. + }) } } diff --git a/src/entities/home.rs b/src/entities/home.rs index 5666a75..5e2ea12 100644 --- a/src/entities/home.rs +++ b/src/entities/home.rs @@ -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. + }) } } diff --git a/src/hitbox.rs b/src/hitbox.rs index bd4170e..32f432f 100644 --- a/src/hitbox.rs +++ b/src/hitbox.rs @@ -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 +} diff --git a/src/main.rs b/src/main.rs index 6ed2dbf..16e2836 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,8 @@ impl App 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 for BugBasherGame { fn key_down(&mut self, key: KeyCode, ctx: &mut AppContext) { 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; } -- cgit v1.2.3