67 lines
1.7 KiB
Rust
67 lines
1.7 KiB
Rust
use std::time::Duration;
|
|
|
|
use bevy::prelude::*;
|
|
use rand::{prelude::*, rng};
|
|
|
|
use crate::{
|
|
FIRST_CORNER_X, FIRST_CORNER_Y, GameObject, SECOND_CORNER_X, SECOND_CORNER_Y,
|
|
ships::{EnemySprite, enemy::spawn_enemy},
|
|
};
|
|
|
|
const MAX_ENEMIES: f32 = 20.0;
|
|
const MIN_TIME: u64 = 2;
|
|
const START_TIME: f32 = 10.0;
|
|
const TIME_PENALTY: f32 = 0.1;
|
|
const ENEMY_INCREASE: f32 = 0.25;
|
|
|
|
#[derive(Component)]
|
|
pub struct EnemySpawner {
|
|
spawn_timer: Timer,
|
|
amount: f32,
|
|
}
|
|
|
|
pub fn setup_enemy_spawner(mut commands: Commands) {
|
|
commands.spawn((
|
|
EnemySpawner {
|
|
spawn_timer: Timer::from_seconds(START_TIME, TimerMode::Repeating),
|
|
amount: 1.,
|
|
},
|
|
GameObject,
|
|
));
|
|
}
|
|
|
|
pub fn tick_enemy_spawner(
|
|
mut commands: Commands,
|
|
time: Res<Time>,
|
|
query: Single<&mut EnemySpawner>,
|
|
sprite: Res<EnemySprite>,
|
|
) {
|
|
let mut spawner = query.into_inner();
|
|
|
|
spawner.spawn_timer.tick(time.delta());
|
|
|
|
if spawner.spawn_timer.just_finished() == false {
|
|
return;
|
|
}
|
|
|
|
let mut random = rng();
|
|
|
|
for _ in 1..((spawner.amount).floor() as u8) {
|
|
let position = Vec2::new(
|
|
random.random_range(FIRST_CORNER_X..SECOND_CORNER_X),
|
|
random.random_range(FIRST_CORNER_Y..SECOND_CORNER_Y),
|
|
);
|
|
|
|
spawn_enemy(&mut commands, sprite.0.clone(), position);
|
|
}
|
|
|
|
if spawner.amount < MAX_ENEMIES {
|
|
spawner.amount += ENEMY_INCREASE;
|
|
} else if spawner.spawn_timer.duration().as_secs() >= MIN_TIME {
|
|
let set_time = spawner.spawn_timer.duration().as_secs_f32() - TIME_PENALTY;
|
|
|
|
spawner
|
|
.spawn_timer
|
|
.set_duration(Duration::from_secs_f32(set_time));
|
|
}
|
|
}
|