diff --git a/src/event.rs b/src/event.rs new file mode 100644 index 0000000..40252d9 --- /dev/null +++ b/src/event.rs @@ -0,0 +1,14 @@ +use bevy::prelude::*; + +/// Signals that the player's ship has been destroyed. +/// Used when the player collides with an asteroid. +#[derive(Event)] +pub(crate) struct ShipDestroy; + +/// Signals that a particular asteroid has been destroyed. +/// Used to split (or vanish) an asteroid when a bullet strikes it. +#[derive(Event)] +pub(crate) struct AsteroidDestroy(pub Entity); + +// TODO: BulletDestroy +// Which depends on the still-pending Bullet component creation. diff --git a/src/lib.rs b/src/lib.rs index 01bf227..5f51fed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,13 @@ mod asteroids; pub mod config; +mod event; mod preparation_widget; mod ship; mod title_screen; use crate::config::{BACKGROUND_COLOR, PLAYER_SHIP_COLOR, SHIP_ROTATION, SHIP_THRUST, WINDOW_SIZE}; -use asteroids::AsteroidSpawner; +use asteroids::{Asteroid, AsteroidSpawner}; use bevy::prelude::*; use bevy_inspector_egui::InspectorOptions; use bevy_inspector_egui::prelude::ReflectInspectorOptions; @@ -49,6 +50,7 @@ impl Plugin for AsteroidPlugin { wrap_entities, asteroids::tick_asteroid_manager, asteroids::spawn_asteroid.after(asteroids::tick_asteroid_manager), + collision_listener, // TODO: Remove debug printing debug_collision_event_printer, ) @@ -59,7 +61,9 @@ impl Plugin for AsteroidPlugin { (integrate_velocity, update_positions, apply_rotation_to_mesh) .run_if(in_state(GameState::Playing)), ) - .add_event::(); + .add_event::() + .add_event::() + .add_event::(); app.insert_state(GameState::TitleScreen); } } @@ -70,6 +74,54 @@ fn debug_collision_event_printer(mut collision_events: EventReader, + mut ship_writer: EventWriter, + mut asteroid_writer: EventWriter, + player: Single>, + rocks: Query<&Asteroid>, +) { + for event in collisions.read() { + if let CollisionEvent::Started(one, two, _flags) = event { + // Valid collisions are: + // + // - Ship & Asteroid + // - Bullet & Asteroid + // + // Asteroids don't collide with each other, bullets don't collide + // with each other, and bullets don't collide with the player ship. + + // Option 1: Ship & Asteroid + if *one == *player { + if rocks.contains(*two) { + // player-asteroid collision + dbg!("Writing ShipDestroy event"); + ship_writer.write(event::ShipDestroy); + } // else, we don't care + } else if *two == *player { + if rocks.contains(*one) { + dbg!("Writing ShipDestroy event"); + ship_writer.write(event::ShipDestroy); + } + } + + // TODO: Bullet-asteroid collisions + } + } +} + #[derive(Clone, Debug, Eq, Hash, PartialEq, States)] pub enum GameState { TitleScreen, // Program is started. Present title screen and await user start