use crate::zombies::{ZombieType, Zombie};
use std::time::{Duration, Instant};
use rand::Rng;
use crate::ui::grid::GRID_HEIGHT;
pub struct ZombieSpawnInfo {
pub zombie_type: ZombieType,
pub row: usize,
}
pub struct LevelController {
last_spawn_time: Instant,
spawn_interval: Duration,
start_time: Instant,
current_wave: usize,
total_waves: usize,
zombies_spawned_in_wave: usize,
zombies_per_wave: usize,
final_wave_announced: bool,
all_zombies_spawned: bool,
waiting_for_first_wave: bool,
}
impl LevelController {
pub fn new() -> Self {
LevelController {
last_spawn_time: Instant::now(),
spawn_interval: Duration::from_secs(2), start_time: Instant::now(),
current_wave: 0,
total_waves: 7, zombies_spawned_in_wave: 0,
zombies_per_wave: 1, final_wave_announced: false,
all_zombies_spawned: false,
waiting_for_first_wave: true,
}
}
pub fn is_final_wave_announced(&mut self) -> bool {
if self.current_wave == self.total_waves - 1 && !self.final_wave_announced {
self.final_wave_announced = true;
return true;
}
false
}
pub fn is_level_completed(&self, zombies: &[Zombie]) -> bool {
if self.all_zombies_spawned && zombies.is_empty() {
return true;
}
false
}
pub fn is_wave_cleared(&self, zombies: &[Zombie]) -> bool {
zombies.is_empty()
}
pub fn update(&mut self, _dt: u64, zombies: &[Zombie]) -> Vec<ZombieSpawnInfo> {
let mut spawns = Vec::new();
let now = Instant::now();
if self.all_zombies_spawned {
return spawns;
}
if self.waiting_for_first_wave {
if now.duration_since(self.start_time) < Duration::from_secs(18) {
return spawns; }
self.waiting_for_first_wave = false;
self.last_spawn_time = now; }
if now.duration_since(self.last_spawn_time) >= self.spawn_interval {
if self.zombies_spawned_in_wave < self.zombies_per_wave {
let mut rng = rand::thread_rng();
let row = rng.gen_range(0..GRID_HEIGHT);
let zombie_type = if self.current_wave >= 3 && rng.gen_range(0..10) < (self.current_wave - 2) {
ZombieType::Conehead
} else {
ZombieType::Normal
};
spawns.push(ZombieSpawnInfo { zombie_type, row });
self.zombies_spawned_in_wave += 1;
self.last_spawn_time = now;
println!("生成僵尸: 波次 {}, 僵尸 {}/{}",
self.current_wave + 1,
self.zombies_spawned_in_wave,
self.zombies_per_wave);
}
else if self.is_wave_cleared(zombies) {
if now.duration_since(self.last_spawn_time) >= Duration::from_secs(6) {
self.current_wave += 1;
if self.current_wave >= self.total_waves {
self.all_zombies_spawned = true;
return spawns;
}
self.zombies_spawned_in_wave = 0;
if self.current_wave == 1 || self.current_wave == 2 {
self.zombies_per_wave = 2;
} else if self.current_wave >= 3 {
self.zombies_per_wave = self.current_wave;
}
if self.current_wave == self.total_waves - 1 {
self.spawn_interval = Duration::from_secs(1);
}
println!("波次 {} 已开始,僵尸数量: {}", self.current_wave + 1, self.zombies_per_wave);
self.last_spawn_time = now; }
}
}
spawns
}
}