warning signs, timer
This commit is contained in:
parent
69fe717b22
commit
dece3a352f
5 changed files with 105 additions and 16 deletions
BIN
assets/sprites/timer.png
Normal file
BIN
assets/sprites/timer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 269 B |
BIN
assets/sprites/warning.png
Normal file
BIN
assets/sprites/warning.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 247 B |
|
|
@ -9,6 +9,7 @@ use bevy::prelude::*;
|
||||||
const ASSETS_NAME: [&str; 3] = ["speed_item.png", "shield_item.png", "kirby_item.png"];
|
const ASSETS_NAME: [&str; 3] = ["speed_item.png", "shield_item.png", "kirby_item.png"];
|
||||||
const COLLECTABLE_COLLIDER_RADIUS: f32 = 50.0;
|
const COLLECTABLE_COLLIDER_RADIUS: f32 = 50.0;
|
||||||
const KIRBY_SPAWN_TIMER_DURATION: Duration = Duration::from_secs(2);
|
const KIRBY_SPAWN_TIMER_DURATION: Duration = Duration::from_secs(2);
|
||||||
|
pub const COLLECTABLE_SCALE: f32 = 2.5;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum CollectableType {
|
pub enum CollectableType {
|
||||||
|
|
@ -33,7 +34,7 @@ pub fn collectable_spawn(
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Collectable(collectable_type),
|
Collectable(collectable_type),
|
||||||
SphereCollider::new(COLLECTABLE_COLLIDER_RADIUS),
|
SphereCollider::new(COLLECTABLE_COLLIDER_RADIUS),
|
||||||
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(2.5)),
|
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(COLLECTABLE_SCALE)),
|
||||||
sprite,
|
sprite,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -42,6 +43,7 @@ pub fn collectable_actions_system(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut kirby_query: Query<(&mut Kirby, &SphereCollider, &Transform)>,
|
mut kirby_query: Query<(&mut Kirby, &SphereCollider, &Transform)>,
|
||||||
collectable_query: Query<(Entity, &Collectable, &SphereCollider, &Transform)>,
|
collectable_query: Query<(Entity, &Collectable, &SphereCollider, &Transform)>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
) {
|
) {
|
||||||
for (mut kirby, kirby_collider, kirby_tf) in &mut kirby_query {
|
for (mut kirby, kirby_collider, kirby_tf) in &mut kirby_query {
|
||||||
for (collectible_entity, collectible, c_collider, collectable_tf) in collectable_query {
|
for (collectible_entity, collectible, c_collider, collectable_tf) in collectable_query {
|
||||||
|
|
@ -54,7 +56,7 @@ pub fn collectable_actions_system(
|
||||||
match &collectible.0 {
|
match &collectible.0 {
|
||||||
CollectableType::SpeedBoost => speed_boost(&mut kirby),
|
CollectableType::SpeedBoost => speed_boost(&mut kirby),
|
||||||
CollectableType::ShieldBoost => shield_boost(&mut kirby),
|
CollectableType::ShieldBoost => shield_boost(&mut kirby),
|
||||||
CollectableType::NewKirby => new_kirby(kirby_pos, &mut commands),
|
CollectableType::NewKirby => new_kirby(kirby_pos, &mut commands, &asset_server),
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.entity(collectible_entity).despawn();
|
commands.entity(collectible_entity).despawn();
|
||||||
|
|
@ -70,15 +72,16 @@ fn shield_boost(kirby: &mut Kirby) {
|
||||||
kirby.shield_factor *= 0.8;
|
kirby.shield_factor *= 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_kirby(kirby_pos: Vec3, commands: &mut Commands) {
|
fn new_kirby(kirby_pos: Vec3, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
||||||
commands.spawn(KirbySpawnHandler {
|
commands.spawn((
|
||||||
timer: Timer::new(KIRBY_SPAWN_TIMER_DURATION, TimerMode::Once),
|
KirbySpawnHandler { timer: Timer::new(KIRBY_SPAWN_TIMER_DURATION, TimerMode::Once), position: kirby_pos },
|
||||||
position: kirby_pos,
|
Sprite::from_image(asset_server.load("sprites/timer.png")),
|
||||||
});
|
Transform::from_translation(kirby_pos).with_scale(Vec3::splat(COLLECTABLE_SCALE)),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[require(DispawnOnGameOver)]
|
#[require(DispawnOnGameOver, Sprite, Transform)]
|
||||||
struct KirbySpawnHandler {
|
struct KirbySpawnHandler {
|
||||||
timer: Timer,
|
timer: Timer,
|
||||||
position: Vec3,
|
position: Vec3,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
use bevy::{ecs::system::SystemParam, prelude::*};
|
use bevy::{ecs::system::SystemParam, prelude::*};
|
||||||
|
|
||||||
use crate::core::{kirby::Kirby, wave::BubbleWaves};
|
use crate::core::{
|
||||||
|
kirby::Kirby,
|
||||||
|
wave::{BubbleWaves, EnnemyWaveLock},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Event)]
|
#[derive(Event)]
|
||||||
pub struct EndGameEvent {
|
pub struct EndGameEvent {
|
||||||
|
|
@ -44,6 +47,7 @@ fn reset_resource<T: Resource + Resetable>(mut res: ResMut<T>) {
|
||||||
#[derive(SystemParam)]
|
#[derive(SystemParam)]
|
||||||
struct GameRes<'w> {
|
struct GameRes<'w> {
|
||||||
bubble_waves: ResMut<'w, BubbleWaves>,
|
bubble_waves: ResMut<'w, BubbleWaves>,
|
||||||
|
ennemy_wave_lock: ResMut<'w, EnnemyWaveLock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_reset_world(
|
fn on_reset_world(
|
||||||
|
|
@ -56,6 +60,7 @@ fn on_reset_world(
|
||||||
commands.entity(e).despawn();
|
commands.entity(e).despawn();
|
||||||
}
|
}
|
||||||
reset_resource(game_res.bubble_waves);
|
reset_resource(game_res.bubble_waves);
|
||||||
|
reset_resource(game_res.ennemy_wave_lock);
|
||||||
println!("Set state");
|
println!("Set state");
|
||||||
commands.set_state(GameState::Starting);
|
commands.set_state(GameState::Starting);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,31 @@
|
||||||
use std::thread::panicking;
|
use std::{thread::panicking, time::Duration};
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::{ecs::system::lifetimeless::SCommands, prelude::*};
|
||||||
use rand::distr::slice::Empty;
|
use rand::distr::slice::Empty;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{
|
core::{
|
||||||
bubble::{Bubble, bubble_spawn_wave},
|
bubble::{Bubble, bubble_spawn_wave},
|
||||||
collectible::{CollectableType, collectable_spawn},
|
collectible::{COLLECTABLE_SCALE, CollectableType, collectable_spawn},
|
||||||
game_state::{EndGameEvent, EndGameReason, Resetable},
|
game_state::{DispawnOnGameOver, EndGameEvent, EndGameReason, Resetable},
|
||||||
kirby::Kirby,
|
kirby::Kirby,
|
||||||
life::Life,
|
life::Life,
|
||||||
},
|
},
|
||||||
map::map::{BOTTOM, LEFT, RIGHT, TOP},
|
map::map::{BOTTOM, LEFT, RIGHT, TOP},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Event)]
|
||||||
|
pub struct NextWaveEvent;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[require(DispawnOnGameOver)]
|
||||||
|
pub struct NextWaveTimer {
|
||||||
|
timer: Timer,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Event)]
|
||||||
|
struct NextWaveTimerTimeout;
|
||||||
|
|
||||||
pub struct BubbleType {
|
pub struct BubbleType {
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
pub move_force: f32,
|
pub move_force: f32,
|
||||||
|
|
@ -97,17 +109,81 @@ impl Resetable for BubbleWaves {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Default)] // Default is false
|
||||||
|
pub struct EnnemyWaveLock(bool);
|
||||||
|
|
||||||
|
impl Resetable for EnnemyWaveLock {
|
||||||
|
fn reset(&mut self) {
|
||||||
|
*self = EnnemyWaveLock::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn no_ennemy_left(bubble_query: Query<(), With<Bubble>>) -> bool {
|
fn no_ennemy_left(bubble_query: Query<(), With<Bubble>>) -> bool {
|
||||||
bubble_query.is_empty()
|
bubble_query.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_wave(mut bubble_wave: ResMut<BubbleWaves>, mut commands: Commands, asset_server: Res<AssetServer>) {
|
#[derive(Component)]
|
||||||
|
#[require(Sprite, Transform, DispawnOnGameOver)]
|
||||||
|
struct WarningSign;
|
||||||
|
|
||||||
|
fn change_wave(
|
||||||
|
mut lock: ResMut<EnnemyWaveLock>,
|
||||||
|
bubble_wave: Res<BubbleWaves>,
|
||||||
|
mut commands: Commands,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
) {
|
||||||
|
// Beetwen moment where all ennemies are killed and NextWaveTimer trigger the spawn of the new ennemy
|
||||||
|
// there is some time, and change_wave will be called every frame during this instance
|
||||||
|
// that's why there is an ugly-ass lock
|
||||||
|
if lock.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lock.0 = true;
|
||||||
let max_bubble_wave = bubble_wave.waves.len();
|
let max_bubble_wave = bubble_wave.waves.len();
|
||||||
if bubble_wave.current_wave >= max_bubble_wave {
|
if bubble_wave.current_wave >= max_bubble_wave {
|
||||||
commands.trigger(EndGameEvent { reason: EndGameReason::Victory });
|
commands.trigger(EndGameEvent { reason: EndGameReason::Victory });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let current_bubble_wave = &bubble_wave.waves[bubble_wave.current_wave];
|
||||||
|
for bubble_splash in current_bubble_wave {
|
||||||
|
commands.spawn((
|
||||||
|
WarningSign,
|
||||||
|
Sprite::from_image(asset_server.load("sprites/warning.png")),
|
||||||
|
Transform::from_translation(bubble_splash.center.extend(0.0)).with_scale(Vec3::splat(COLLECTABLE_SCALE)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("change wave");
|
||||||
|
commands.trigger(NextWaveEvent);
|
||||||
|
commands.spawn((NextWaveTimer { timer: Timer::new(Duration::from_secs(1), TimerMode::Once) },));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_wave_timer_system(
|
||||||
|
next_wave_timer_query: Single<(&mut NextWaveTimer, Entity)>,
|
||||||
|
time: Res<Time>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
let (mut next_wave_timer, timer_id) = next_wave_timer_query.into_inner();
|
||||||
|
next_wave_timer.timer.tick(time.delta());
|
||||||
|
if next_wave_timer.timer.is_finished() {
|
||||||
|
commands.trigger(NextWaveTimerTimeout);
|
||||||
|
commands.entity(timer_id).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_warning_sign(_: On<NextWaveTimerTimeout>, mut commands: Commands, query: Query<Entity, With<WarningSign>>) {
|
||||||
|
for entity in query {
|
||||||
|
commands.entity(entity).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_wave_ennemy(
|
||||||
|
_: On<NextWaveTimerTimeout>,
|
||||||
|
mut commands: Commands,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
mut bubble_wave: ResMut<BubbleWaves>,
|
||||||
|
mut lock: ResMut<EnnemyWaveLock>,
|
||||||
|
) {
|
||||||
let wave = &bubble_wave.waves[bubble_wave.current_wave];
|
let wave = &bubble_wave.waves[bubble_wave.current_wave];
|
||||||
let collectables = &bubble_wave.collectables[bubble_wave.current_wave];
|
let collectables = &bubble_wave.collectables[bubble_wave.current_wave];
|
||||||
|
|
||||||
|
|
@ -115,8 +191,8 @@ fn change_wave(mut bubble_wave: ResMut<BubbleWaves>, mut commands: Commands, ass
|
||||||
for (collectable_type, collectable_pos) in collectables {
|
for (collectable_type, collectable_pos) in collectables {
|
||||||
collectable_spawn(&mut commands, &asset_server, *collectable_type, *collectable_pos);
|
collectable_spawn(&mut commands, &asset_server, *collectable_type, *collectable_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bubble_wave.current_wave += 1;
|
bubble_wave.current_wave += 1;
|
||||||
|
lock.0 = false; // Release lock, ennemy wave is spawnned
|
||||||
}
|
}
|
||||||
|
|
||||||
fn heal_kirby(query: Query<&mut Life, With<Kirby>>) {
|
fn heal_kirby(query: Query<&mut Life, With<Kirby>>) {
|
||||||
|
|
@ -129,6 +205,11 @@ pub struct WavePlugin;
|
||||||
|
|
||||||
impl Plugin for WavePlugin {
|
impl Plugin for WavePlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.insert_resource(get_bubble_waves()).add_systems(Update, (change_wave, heal_kirby).run_if(no_ennemy_left));
|
app.insert_resource(get_bubble_waves())
|
||||||
|
.insert_resource(EnnemyWaveLock::default())
|
||||||
|
.add_systems(Update, (change_wave, heal_kirby).run_if(no_ennemy_left))
|
||||||
|
.add_systems(Update, next_wave_timer_system)
|
||||||
|
.add_observer(spawn_wave_ennemy)
|
||||||
|
.add_observer(delete_warning_sign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue