From 804206beeb82671552ccd9b689b303a1251fade0 Mon Sep 17 00:00:00 2001 From: Raymond Hogenson Date: Sat, 18 Aug 2018 00:49:15 -0400 Subject: Finalize the new movement scheme Ok it's pretty fucking cool. Tracking acceleration has always looked good, no matter what. There's some pretty advanced logic going on here, and it's worth it. --- src/state.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/state.rs b/src/state.rs index 74ac73b..e2ca280 100644 --- a/src/state.rs +++ b/src/state.rs @@ -15,10 +15,15 @@ pub struct EBullet { d_y: f64, } +enum EnemyStatus { + Accel, + Travel, + Decel, +} + pub struct Enemy { - pub x: i32, - pub y: i32, - action_count: u64, + pub x: f64, + pub y: f64, v_x: f64, v_y: f64, a_x: f64, @@ -65,34 +70,64 @@ fn random_bullet(enemy: &Enemy) -> EBullet { let theta: f64 = rand::random::()*2.*std::f64::consts::PI/3. + std::f64::consts::PI/6.; let dx = f64::cos(theta) * multiplier; let dy = f64::sin(theta) * multiplier; - EBullet::new(enemy.x, dx, enemy.y, dy) + EBullet::new(enemy.x.round() as i32, dx, enemy.y.round() as i32, dy) } fn random_position() -> (f64, f64) { - (rand::random() * (constants::X_DIM - 200) as f64 + 100., rand::random() * 200) + (rand::random::() * (constants::X_DIM - 200) as f64 + 100., rand::random::() * 100.) +} + +fn shorten(x: f64, y: f64, maxlen: f64) -> (f64, f64) { + let len = f64::sqrt(x*x + y*y); + if len > maxlen { + (x / len / 2., y / len / 2.) + } else { + (x, y) + } } impl Enemy { pub fn new() -> Enemy { - Enemy { x: 200, y: 40, action_count: 1, v_x: 0., v_y: 0., a_x: 0., a_y: 0., radius: 30, health: STARTING_HEALTH, target_x: 200, target_y: 400 } + let (x, y) = random_position(); + Enemy { x: 200., y: 40., v_x: 0., v_y: 0., a_x: 0., a_y: 0., radius: 30, health: STARTING_HEALTH, target_x: x, target_y: y } } pub fn act(&mut self, count: u64) -> Vec { - let dx = self.target_x - self.x; - let dy = self.target_y - self.y; - /* Made it; pick a new destination */ - if f64::sqrt(dx*dx + dy*dy) < 10 { - let (self.target_x, self.target_y) = random_position(); + let dx = self.target_x - self.x as f64; + let dy = self.target_y - self.y as f64; + let vec_x = self.target_x - self.x; + let vec_y = self.target_y - self.y; + let (x, y) = shorten(vec_x, vec_y, 0.25); + self.a_x = x; + self.a_y = y; + + /* Except that if we're really close, we actually should just slow down */ + if f64::sqrt(dx*dx + dy*dy) < 100. { + let (x, y) = shorten(-self.v_x, -self.v_y, 0.25); + self.a_x = x; + self.a_y = y; + /* And, if we're close and we managed to slow down, we'll pick a new target */ + if f64::sqrt(self.v_x*self.v_x + self.v_y*self.v_y) < 0.1 { + let (x, y) = random_position(); + self.target_x = x; + self.target_y = y; + } + } + /* Close enough */ + + /* If we're too fast, don't go faster */ + if f64::sqrt(self.v_x*self.v_x + self.v_y*self.v_y) > 10. { + if self.v_x.signum() == self.a_x.signum() { + self.a_x = 0.; + } + if self.v_y.signum() == self.a_y.signum() { + self.a_y = 0.; + } } - let vec_x = self.target_x - self.real_x; - let vec_y = self.target_y - self.real_y; - let len = f64::sqrt(vec_x*vec_x + vec_y*vec_y); - self.a_x = vec_x / len / 2.; - self.a_y = vec_y / len / 2.; self.v_x += self.a_x; - self.x = (self.x as f64 + self.v_x).round() as i32; + self.x += self.v_x; self.v_y += self.a_y; - self.y = (self.y as f64 + self.v_y).round() as i32; + self.y += self.v_y; if count % 20 == 0 { let num_bullets; if self.health >= 80 { @@ -185,10 +220,10 @@ impl Positioned for PBullet { impl Positioned for Enemy { fn x(&self) -> i32 { - self.x + self.x.round() as i32 } fn y(&self) -> i32 { - self.y + self.y.round() as i32 } fn radius(&self) -> u32 { self.radius -- cgit v1.3.1