diff options
| author | LLLL Colonq <llll@colonq> | 2026-08-18 00:08:28 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-08-18 00:08:28 -0400 |
| commit | 32a62cfcb925225359a5c90761b795f2f737ebd2 (patch) | |
| tree | 95c2261964803b19f2d39cb35d8d514ed6e5a6f4 /2026/games_submissions/asrael_io/source/src/enemy.rs | |
| parent | de99c5f7636a952025ea13de02bafd25bcb6bdec (diff) | |
Re-populate games
Diffstat (limited to '2026/games_submissions/asrael_io/source/src/enemy.rs')
| -rw-r--r-- | 2026/games_submissions/asrael_io/source/src/enemy.rs | 174 |
1 files changed, 0 insertions, 174 deletions
diff --git a/2026/games_submissions/asrael_io/source/src/enemy.rs b/2026/games_submissions/asrael_io/source/src/enemy.rs deleted file mode 100644 index 46eabc0..0000000 --- a/2026/games_submissions/asrael_io/source/src/enemy.rs +++ /dev/null @@ -1,174 +0,0 @@ -use crate::color::Palette; -use crate::color::db32::{LIGHT_RED, PINK, PURPLE}; -use crate::gfx; -use crate::math; -use crate::rng::Rng; -use crate::sprite::Sprite; -use crate::{GAME_H, GAME_W}; - -use std::f32::consts::TAU; - -use aseprite::AsepriteFile; -use glam::Vec2; - -const ROT_STEPS: f32 = 16.0; - -#[derive(Default)] -enum State { - Dive { - path: [Vec2; 4], - fired: u32, - shots: u32, - t: f32, - }, - #[default] - Formation, -} - -pub struct Enemy { - base: Vec2, - flash: u32, - hp: u32, - pos: Vec2, - step: Vec2, - sprite: Sprite, - state: State, -} - -impl Enemy { - pub fn new(sprites: &AsepriteFile, layer: &str, base: Vec2, hp: u32) -> Self { - let pos = base; - let step = Vec2::ZERO; - let sprite = Sprite::from_ase(sprites, layer); - let state = State::default(); - - Self { - base, - flash: 0, - hp, - pos, - step, - sprite, - state, - } - } - - pub fn damage(&mut self) -> bool { - self.hp = self.hp.saturating_sub(1); - self.flash = 12; - self.hp == 0 - } - - pub fn center(&self) -> Vec2 { - self.pos + self.size() / 2.0 - } - - pub fn pos(&self) -> Vec2 { - self.pos - } - - pub fn size(&self) -> Vec2 { - self.sprite.size.as_vec2() - } - - pub fn start_dive(&mut self, player_x: f32, shots: u32, rng: &mut Rng) { - if matches!(self.state, State::Dive { .. }) { - return; - } - - let side = if self.pos.x < 70.0 { - 1.0 - } else if self.pos.x > GAME_W as f32 - 70.0 { - -1.0 - } else if rng.chance(0.5) { - 1.0 - } else { - -1.0 - }; - - let min = Vec2::new(4.0, 4.0); - let max = Vec2::new(GAME_W as f32 - 20.0, GAME_H as f32 - 20.0); - let swing = (self.pos + Vec2::new(side * 70.0, -40.0)).clamp(min, max); - let plunge = Vec2::new(player_x, GAME_H as f32 - 20.0).clamp(min, max); - - let path = [self.pos, swing, plunge, self.base]; - - self.state = State::Dive { - path, - fired: 0, - shots, - t: 0.0, - }; - } - - pub fn update(&mut self, sway: f32, player: Vec2) -> Option<Vec2> { - let before = self.pos; - let mut shot = None; - - self.flash = self.flash.saturating_sub(1); - - match &mut self.state { - State::Formation => { - let target = self.base.x + sway; - self.pos.x += (target - self.pos.x) * 0.2; - } - - State::Dive { - path, - fired, - shots, - t, - } => { - *t += 1.0 / 240.0; - - if *t >= 1.0 { - self.pos = self.base; - self.state = State::Formation; - } else { - self.pos = math::bezier(*path, *t); - - let center = self.pos + self.sprite.size.as_vec2() / 2.0; - let facing = self.step.normalize_or_zero(); - let to_player = (player - center).normalize_or_zero(); - - let next = 0.25 + 0.5 * *fired as f32 / *shots as f32; - if *fired < *shots && *t > next && facing.dot(to_player) > 0.8 { - *fired += 1; - shot = Some(center); - } - } - } - } - - self.step = self.pos - before; - shot - } - - pub fn draw(&self, frame: &mut [u32], palette: &Palette, a: f32, tick: u32) { - let pos = self.pos - self.step * (1.0 - a); - let tint = if self.flash > 0 && (tick / 2).is_multiple_of(2) { - LIGHT_RED - } else { - 0 - }; - - if matches!(self.state, State::Dive { .. }) && self.step.length_squared() > 0.001 { - let dir = self.step.normalize(); - let angle = (-dir.x).atan2(dir.y); - let angle = (angle * ROT_STEPS / TAU).round() * (TAU / ROT_STEPS); - let center = pos + self.sprite.size.as_vec2() / 2.0; - self.sprite - .draw_rotated(frame, palette, center, angle, tint); - - let half = self.sprite.size.y as f32 / 2.0; - for i in 0..3 { - let tail = center - dir * (half + 1.0 + i as f32 * 2.0); - let c = [PURPLE, PINK][(tick / 4 + i) as usize % 2]; - gfx::blit(frame, palette, &[c], tail.round().as_ivec2(), 1, 0); - } - } else { - self.sprite - .draw_tinted(frame, palette, pos.round().as_ivec2(), tint); - } - } -} |
