Enemy spawner

This commit is contained in:
Rendo 2025-11-18 00:48:25 +05:00
commit a34085655a
2 changed files with 77 additions and 15 deletions

View file

@ -0,0 +1,67 @@
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));
}
}

View file

@ -1,15 +1,18 @@
use bevy::prelude::*;
use rand::{prelude::*, rng};
use crate::{
FIRST_CORNER_X, FIRST_CORNER_Y, GameState, SECOND_CORNER_X, SECOND_CORNER_Y,
ships::enemy::spawn_enemy,
GameState,
ships::enemy_spawner::{setup_enemy_spawner, tick_enemy_spawner},
};
pub mod enemy;
pub mod enemy_spawner;
pub mod gun;
pub mod player;
#[derive(Resource)]
pub struct EnemySprite(Handle<Image>);
#[derive(Component, Copy, Clone, PartialEq, Eq)]
pub enum Factions {
PlayerFaction,
@ -36,7 +39,7 @@ pub struct ShipsPlugin;
impl Plugin for ShipsPlugin {
fn build(&self, app: &mut bevy::app::App) {
app.insert_resource(Time::<Fixed>::from_hz(60.))
.add_systems(OnEnter(GameState::Game), startup)
.add_systems(OnEnter(GameState::Game), (startup, setup_enemy_spawner))
.add_systems(
FixedUpdate,
(
@ -46,6 +49,7 @@ impl Plugin for ShipsPlugin {
enemy::enemy_ai_system.run_if(in_state(GameState::Game)),
),
)
.add_systems(Update, tick_enemy_spawner)
.add_observer(player::player_death_observer);
}
}
@ -54,16 +58,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
let player_sprite: Handle<Image> = asset_server.load("player.png");
let enemy_sprite: Handle<Image> = asset_server.load("enemy.png");
commands.insert_resource(EnemySprite(enemy_sprite));
player::spawn_player(&mut commands, player_sprite, Vec2::new(0., 0.));
let mut random = rng();
for _ in 0..50 {
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, enemy_sprite.clone(), position);
}
}