diff --git a/src/drops.rs b/src/drops.rs index 7815ad3..18d1a2e 100644 --- a/src/drops.rs +++ b/src/drops.rs @@ -7,7 +7,11 @@ use bevy_rand::prelude::*; use bevy_rapier2d::prelude::*; use rand::Rng; -use crate::{player::Player, scene::SceneObj, METER}; +use crate::{ + player::{LifeChangeEvent, Player}, + scene::SceneObj, + METER, +}; #[derive(Component)] struct SpawnTimer(pub Timer); @@ -27,7 +31,13 @@ pub fn spawner_plugin(app: &mut App) { .add_systems(Startup, add_timer) .add_systems( Update, - (drop_crates, do_drop, crate_collisions, delete_on_env_coll), + ( + drop_crates, + do_drop, + crate_collisions, + delete_on_env_coll, + player_coll, + ), ); } @@ -130,10 +140,27 @@ fn delete_on_env_coll(mut ev_colls: EventReader, mut commands: C if let CollisionType::Player(_) = with { continue; } - // let CollisionType::Scene(obj) = with else { - // unreachable!() - // }; - commands.entity(*coll_crate).despawn(); + if let Some(mut e) = commands.get_entity(*coll_crate) { + e.despawn(); + } + } +} + +fn player_coll( + mut ev_colls: EventReader, + mut ev_lives: EventWriter, + mut commands: Commands, +) { + for CrateCollision { coll_crate, with } in ev_colls.read() { + if let CollisionType::Scene(_) = with { + continue; + } + + ev_lives.send(LifeChangeEvent::Lost); + + if let Some(mut e) = commands.get_entity(*coll_crate) { + e.despawn(); + } } } diff --git a/src/main.rs b/src/main.rs index 79860b6..e3abb07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use bevy::{ }; use bevy_rapier2d::prelude::*; use drops::spawner_plugin; +use player::LifeChangeEvent; const METER: f32 = 48.; fn main() { @@ -19,12 +20,12 @@ fn main() { .insert_resource(rapier_config) .add_plugins(RapierPhysicsPlugin::::pixels_per_meter(METER)) .add_plugins(RapierDebugRenderPlugin::default()) - .add_plugins((spawner_plugin)) - .add_systems(Startup, (scene::setup_scene, setup_cam, player::add_player)) - .add_systems( - Update, - (player::move_player, player::player_ground_collision), - ) + .add_plugins(( + spawner_plugin, + game_state::state_and_ui_plugin, + player::player_plugin, + )) + .add_systems(Startup, (scene::setup_scene, setup_cam)) .run() } @@ -38,3 +39,62 @@ fn setup_cam(mut commands: Commands) { mod drops; mod player; mod scene; +mod game_state { + use bevy::{prelude::*, time::Stopwatch}; + + #[derive(Component)] + pub struct GameState { + score: u32, + game_time: Stopwatch, + } + + #[derive(Component)] + struct StateText; + + pub fn state_and_ui_plugin(app: &mut App) { + app.add_systems(Startup, (setup_gamestate, setup_ui)) + .add_systems(Update, (update_time)); + } + + fn setup_gamestate(mut commands: Commands) { + commands.spawn(GameState { + score: 0, + game_time: Stopwatch::new(), + }); + } + + fn setup_ui(mut commands: Commands) { + commands.spawn(( + TextBundle::from_sections([ + TextSection::new("Score: ", TextStyle::default()), + TextSection::new("0", TextStyle::default()), + TextSection::new("\n", TextStyle::default()), + TextSection::new("Time: ", TextStyle::default()), + TextSection::new("0", TextStyle::default()), + TextSection::new("s", TextStyle::default()), + ]) + .with_style(Style { + position_type: PositionType::Absolute, + top: Val::Px(5.0), + right: Val::Px(5.0), + ..default() + }), + StateText, + )); + } + + fn update_time( + mut state_txt: Query<&mut Text, With>, + mut game_state: Query<&mut GameState>, + time: Res