//! Blob — the basic enemy. Mirrors `crate::weapons::impact::Impact` on the weapon side.
use std::collections::HashMap;
use macroquad::{color::Color, math::Vec2, shapes::draw_circle};
use crate::{
animations::AnimationTypes,
enemies::{EnemyKind, behaviors::SplitOnDeath, movement::SeekCenter},
enemy::Enemy,
registry::EnemyID,
types::Source,
};
pub struct Blob;
impl Blob {
const BASE_XP: f32 = 1.0;
const BASE_HP: f32 = 1.0;
const HP_GROWTH: f32 = 1.6;
const XP_GROWTH: f32 = 1.3;
}
impl EnemyKind for Blob {
fn create(tier: u32) -> Enemy {
let hp = (Self::BASE_HP * Self::HP_GROWTH.powf(tier as f32)).round();
let xp = (Self::BASE_XP * Self::XP_GROWTH.powf(tier as f32)).round();
let mut template = Enemy {
id: 0,
pos: Vec2::ZERO,
hp,
tier,
radius: 10.,
kind: EnemyID::PLACEHOLDER, // stamped with the real id by EnemyRegistry::make
death_anim: AnimationTypes::EnemeyDeathAnimation,
statuses: Vec::new(),
killer: Source::None,
resists: HashMap::new(),
xp: xp as u32,
behaviors: Vec::new(),
draw: Blob::animation(),
max_hp: hp,
vel: Vec2::ZERO,
};
template.behaviors.push(SplitOnDeath::create(3));
template.behaviors.push(SeekCenter::create(0));
template
}
fn animation() -> Box<fn(&Enemy) -> ()> {
let animation = |enemy: &Enemy| {
let hp_frac = (enemy.hp / enemy.max_hp).clamp(0.0, 1.0);
let col = Color::new(0.3, hp_frac * 0.2, hp_frac * 0.2, 1.0);
draw_circle(enemy.pos.x, enemy.pos.y, enemy.radius, col);
};
Box::new(animation)
}
}