diff options
| -rw-r--r-- | src/state.rs | 75 |
1 files changed, 55 insertions, 20 deletions
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::<f64>()*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::<f64>() * (constants::X_DIM - 200) as f64 + 100., rand::random::<f64>() * 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<EBullet> { - 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 |
