game state and restart, but at what cost?? (my mental health)
This commit is contained in:
parent
4b9101ad2c
commit
002ad4a162
11 changed files with 143 additions and 23 deletions
|
|
@ -5,6 +5,7 @@ use rand::Rng;
|
|||
|
||||
use crate::{
|
||||
core::{
|
||||
game_state::DispawnOnGameOver,
|
||||
kirby::Kirby,
|
||||
life::{DamageDealer, Life},
|
||||
wave::BubbleSplash,
|
||||
|
|
@ -13,7 +14,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Sprite, PhysicsBody, DensityObject, Life, DamageDealer, SphereCollider)]
|
||||
#[require(Sprite, PhysicsBody, DensityObject, Life, DamageDealer, SphereCollider, DispawnOnGameOver)]
|
||||
pub struct Bubble {
|
||||
move_force: f32,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::core::game_state::{DispawnOnGameOver, GameStartupSet, GameState};
|
||||
use crate::core::kirby::{Kirby, kirby_spawn};
|
||||
use crate::physics::sphere_collider::SphereCollider;
|
||||
use bevy::prelude::*;
|
||||
|
|
@ -17,7 +18,7 @@ pub enum CollectableType {
|
|||
}
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(SphereCollider, Sprite)]
|
||||
#[require(SphereCollider, Sprite, DispawnOnGameOver)]
|
||||
pub struct Collectable(CollectableType);
|
||||
|
||||
// Not a system.
|
||||
|
|
@ -83,6 +84,7 @@ fn new_kirby(kirby_pos: Vec3, commands: &mut Commands) {
|
|||
}
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(DispawnOnGameOver)]
|
||||
struct KirbySpawnHandler {
|
||||
timer: Timer,
|
||||
position: Vec3,
|
||||
|
|
@ -108,7 +110,7 @@ pub struct CollectablePlugin;
|
|||
|
||||
impl Plugin for CollectablePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, collectable_spawner_init)
|
||||
app.add_systems(OnEnter(GameState::Starting), collectable_spawner_init.in_set(GameStartupSet))
|
||||
.add_systems(FixedUpdate, collectable_actions_system)
|
||||
.add_systems(Update, kirby_spawn_timer);
|
||||
}
|
||||
|
|
|
|||
87
src/core/game_state.rs
Normal file
87
src/core/game_state.rs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
use bevy::{ecs::system::SystemParam, prelude::*};
|
||||
|
||||
use crate::core::{kirby::Kirby, wave::BubbleWaves};
|
||||
|
||||
#[derive(Event)]
|
||||
struct EndGameEvent {
|
||||
pub reason: EndGameReason,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum EndGameReason {
|
||||
Die,
|
||||
Victory,
|
||||
}
|
||||
|
||||
fn no_kirbies_emetter(mut commands: Commands, query: Query<(), With<Kirby>>) {
|
||||
if query.is_empty() {
|
||||
commands.trigger(EndGameEvent { reason: EndGameReason::Die });
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum GameState {
|
||||
#[default]
|
||||
Starting,
|
||||
Running,
|
||||
Paused,
|
||||
}
|
||||
|
||||
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
|
||||
pub struct GameStartupSet;
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct DispawnOnGameOver;
|
||||
|
||||
pub trait Resetable {
|
||||
fn reset(&mut self);
|
||||
}
|
||||
|
||||
fn reset_resource<T: Resource + Resetable>(mut res: ResMut<T>) {
|
||||
res.reset();
|
||||
}
|
||||
|
||||
#[derive(SystemParam)]
|
||||
struct GameRes<'w> {
|
||||
bubble_waves: ResMut<'w, BubbleWaves>,
|
||||
}
|
||||
|
||||
fn on_reset_world(
|
||||
_: On<ResetWorldEvent>,
|
||||
mut commands: Commands,
|
||||
entities: Query<Entity, With<DispawnOnGameOver>>,
|
||||
game_res: GameRes,
|
||||
) {
|
||||
for e in &entities {
|
||||
commands.entity(e).despawn();
|
||||
}
|
||||
reset_resource(game_res.bubble_waves);
|
||||
println!("Set state");
|
||||
commands.set_state(GameState::Starting);
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
struct ResetWorldEvent;
|
||||
|
||||
fn on_end_game(event: On<EndGameEvent>, mut commands: Commands) {
|
||||
let reason = event.reason;
|
||||
println!("end game reason {:?}", reason);
|
||||
commands.trigger(ResetWorldEvent);
|
||||
}
|
||||
|
||||
fn change_to_running_state(mut commands: Commands) {
|
||||
println!("Running state !");
|
||||
commands.set_state(GameState::Running);
|
||||
}
|
||||
|
||||
pub struct GameEventsPlugin;
|
||||
|
||||
impl Plugin for GameEventsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_state::<GameState>()
|
||||
.add_systems(Update, no_kirbies_emetter.run_if(in_state(GameState::Running)))
|
||||
.add_systems(OnEnter(GameState::Starting), change_to_running_state.after(GameStartupSet))
|
||||
.add_observer(on_end_game)
|
||||
.add_observer(on_reset_world);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +1,23 @@
|
|||
use crate::core::game_state::{GameStartupSet, DispawnOnGameOver};
|
||||
use bevy::prelude::*;
|
||||
|
||||
const KIRBY_SCALE: f32 = 3.0;
|
||||
|
||||
use crate::{
|
||||
core::life::{DamageDealer, Life},
|
||||
core::{
|
||||
game_state::GameState,
|
||||
life::{DamageDealer, Life},
|
||||
},
|
||||
juice::animation::{AnimationIndices, AnimationTimer},
|
||||
physics::physics_body::PhysicsBody,
|
||||
physics::sphere_collider::SphereCollider,
|
||||
physics::{physics_body::PhysicsBody, sphere_collider::SphereCollider},
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Transform, SphereCollider, DamageDealer)]
|
||||
#[require(Transform, SphereCollider, DamageDealer, DispawnOnGameOver)]
|
||||
pub struct SuckArea;
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Sprite, PhysicsBody, SphereCollider, AnimationIndices, Life)]
|
||||
#[require(Sprite, PhysicsBody, SphereCollider, AnimationIndices, Life, DispawnOnGameOver)]
|
||||
pub struct Kirby {
|
||||
pub speed_force: f32,
|
||||
pub is_sucking: bool,
|
||||
|
|
@ -26,6 +29,7 @@ pub fn kirby_spawn_start(
|
|||
asset_server: Res<AssetServer>,
|
||||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
||||
) {
|
||||
println!("Start Kirby");
|
||||
kirby_spawn(&mut commands, &asset_server, &mut texture_atlas_layouts, Vec3::ZERO);
|
||||
// kirby_spawn(&mut commands, &asset_server, &mut texture_atlas_layouts, Vec3 { x: 500.0, y: 0.0, z: 0.0 });
|
||||
}
|
||||
|
|
@ -52,7 +56,7 @@ pub fn kirby_spawn(
|
|||
SphereCollider::new(20.0),
|
||||
animation_indices,
|
||||
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
||||
Life::new(1000.0),
|
||||
Life::new(10.0),
|
||||
Transform::from_translation(pos).with_scale(Vec3::splat(KIRBY_SCALE)),
|
||||
))
|
||||
.id();
|
||||
|
|
@ -119,6 +123,7 @@ pub struct KirbyPlugin;
|
|||
|
||||
impl Plugin for KirbyPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, kirby_spawn_start).add_systems(FixedUpdate, kirby_actions);
|
||||
app.add_systems(OnEnter(GameState::Starting), kirby_spawn_start.in_set(GameStartupSet))
|
||||
.add_systems(FixedUpdate, kirby_actions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
core::bubble::Bubble,
|
||||
core::counter::{BubbleExplodedCountThisFrame, BubbleSuckedCountThisFrame, KirbyHitCountThisFrame},
|
||||
core::kirby::{Kirby, SuckArea},
|
||||
core::{
|
||||
bubble::Bubble,
|
||||
counter::{BubbleExplodedCountThisFrame, BubbleSuckedCountThisFrame, KirbyHitCountThisFrame},
|
||||
game_state::DispawnOnGameOver,
|
||||
kirby::{Kirby, SuckArea},
|
||||
},
|
||||
physics::sphere_collider::SphereCollider,
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(DispawnOnGameOver)]
|
||||
pub struct Life {
|
||||
max_life: f32,
|
||||
current_life: f32,
|
||||
|
|
@ -42,7 +46,7 @@ pub fn despawn_if_dead(mut commands: Commands, query: Query<(Entity, &Life)>) {
|
|||
}
|
||||
|
||||
#[derive(Component, Default)]
|
||||
#[require(SphereCollider)]
|
||||
#[require(SphereCollider, DispawnOnGameOver)]
|
||||
pub struct DamageDealer {
|
||||
damage_strength: f32,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
pub mod bubble;
|
||||
pub mod collectible;
|
||||
pub mod counter;
|
||||
pub mod game_state;
|
||||
pub mod kirby;
|
||||
pub mod life;
|
||||
pub mod wave;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@ use bevy::prelude::*;
|
|||
use rand::distr::slice::Empty;
|
||||
|
||||
use crate::{
|
||||
core::bubble::{Bubble, bubble_spawn_wave},
|
||||
core::{
|
||||
bubble::{Bubble, bubble_spawn_wave},
|
||||
game_state::Resetable,
|
||||
kirby::Kirby,
|
||||
life::Life,
|
||||
},
|
||||
map::map::{BOTTOM, LEFT, RIGHT, TOP},
|
||||
};
|
||||
|
||||
|
|
@ -50,7 +55,7 @@ const GREEN_BUBBLE: BubbleType = BubbleType {
|
|||
|
||||
#[derive(Resource)]
|
||||
pub struct BubbleWaves {
|
||||
pub waves: Vec<Vec<BubbleSplash>>,
|
||||
waves: Vec<Vec<BubbleSplash>>,
|
||||
pub current_wave: usize,
|
||||
}
|
||||
|
||||
|
|
@ -75,6 +80,12 @@ fn get_bubble_waves() -> BubbleWaves {
|
|||
}
|
||||
}
|
||||
|
||||
impl Resetable for BubbleWaves {
|
||||
fn reset(&mut self) {
|
||||
*self = get_bubble_waves();
|
||||
}
|
||||
}
|
||||
|
||||
fn no_ennemy_left(bubble_query: Query<(), With<Bubble>>) -> bool {
|
||||
bubble_query.is_empty()
|
||||
}
|
||||
|
|
@ -88,10 +99,16 @@ fn change_wave(mut bubble_wave: ResMut<BubbleWaves>, mut commands: Commands, ass
|
|||
bubble_spawn_wave(&mut commands, &asset_server, bubble_wave.waves[bubble_wave.current_wave].as_slice());
|
||||
}
|
||||
|
||||
fn heal_kirby(query: Query<&mut Life, With<Kirby>>) {
|
||||
for mut kirby_life in query {
|
||||
kirby_life.heal(f32::MAX);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WavePlugin;
|
||||
|
||||
impl Plugin for WavePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(get_bubble_waves()).add_systems(Update, change_wave.run_if(no_ennemy_left));
|
||||
app.insert_resource(get_bubble_waves()).add_systems(Update, (change_wave, heal_kirby).run_if(no_ennemy_left));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use crate::core::game_state::DispawnOnGameOver;
|
||||
use bevy::prelude::*;
|
||||
// Source : https://bevy.org/examples/2d-rendering/sprite-sheet/
|
||||
|
||||
#[derive(Component, Default)]
|
||||
#[require(DispawnOnGameOver)]
|
||||
pub struct AnimationIndices {
|
||||
pub first: usize,
|
||||
pub last: usize,
|
||||
|
|
@ -15,6 +16,7 @@ impl AnimationIndices {
|
|||
}
|
||||
|
||||
#[derive(Component, Deref, DerefMut)]
|
||||
#[require(DispawnOnGameOver)]
|
||||
pub struct AnimationTimer(pub Timer);
|
||||
|
||||
pub fn animate_sprite(time: Res<Time>, mut query: Query<(&AnimationIndices, &mut AnimationTimer, &mut Sprite)>) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ mod juice;
|
|||
use juice::animation::animate_sprite;
|
||||
use juice::camera::MyCameraPlugin;
|
||||
|
||||
use crate::core::game_state::GameEventsPlugin;
|
||||
use crate::core::wave::WavePlugin;
|
||||
|
||||
fn main() {
|
||||
|
|
@ -34,6 +35,7 @@ fn main() {
|
|||
}),
|
||||
..default()
|
||||
}))
|
||||
.add_plugins(GameEventsPlugin)
|
||||
.add_plugins(CounterPlugin)
|
||||
.add_plugins(KirbyPlugin)
|
||||
.add_plugins(DensityGridPlugin)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use bevy::prelude::*;
|
|||
use rand::Rng;
|
||||
|
||||
pub static MAX_MAP_WIDTH: usize = 1024;
|
||||
use crate::physics::physics_body::PhysicsBody;
|
||||
use crate::{core::game_state::GameState, physics::physics_body::PhysicsBody};
|
||||
|
||||
const CELL_SIZE: usize = 8;
|
||||
const MAX_MAP_SIZE: usize = MAX_MAP_WIDTH * 2;
|
||||
|
|
@ -78,11 +78,9 @@ pub fn density_grid_force(
|
|||
let index = get_index_from_uvec2(neighbor_cell);
|
||||
let density = density_grid.grid[index];
|
||||
|
||||
// println!("offset : {:?} density: {:?}", offset.as_vec2(), density);
|
||||
density_gradient += offset.as_vec2() * density as f32;
|
||||
}
|
||||
}
|
||||
// println!("density : {:?}", density_gradient);
|
||||
density_gradient += density_obj.random_offset; // To not have a "grid" thingy
|
||||
physics_body.force -= density_gradient * DENSITY_FORCE_SCALE;
|
||||
}
|
||||
|
|
@ -93,7 +91,7 @@ pub struct DensityGridPlugin;
|
|||
impl Plugin for DensityGridPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(DensityGrid::new())
|
||||
.add_systems(PostStartup, init_density_object)
|
||||
.add_systems(OnExit(GameState::Starting), init_density_object)
|
||||
.add_systems(FixedUpdate, (density_grid_update, density_grid_force).chain());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::core::game_state::DispawnOnGameOver;
|
||||
use crate::map::map::MapBounds;
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Transform)]
|
||||
#[require(Transform, DispawnOnGameOver)]
|
||||
pub struct PhysicsBody {
|
||||
pub mass: f32,
|
||||
pub force: Vec2,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue