Handle player ship destruction... some of it...
Some checks failed
Basic checks / Basic build-and-test supertask (push) Has been cancelled

The player will be respawned, their lives decreased, and the board
cleared. The UI doesn't update, and the sudden snap to a freshly reset
board is quite jarring. The state transition to GameOver stops the game,
but there isn't anything else running in that state so it just looks
frozen.

Basically, there's a ton left to do, but technically I have handled
player ship destruction!
This commit is contained in:
2025-08-10 21:29:25 -05:00
parent 45b1fe751f
commit 804186ea2f
2 changed files with 39 additions and 2 deletions

View File

@@ -57,6 +57,7 @@ impl Plugin for AsteroidPlugin {
asteroids::spawn_asteroid.after(asteroids::tick_asteroid_manager),
asteroids::split_asteroids,
ship::bullet_impact_listener,
ship::ship_impact_listener,
collision_listener,
// TODO: Remove debug printing
debug_collision_event_printer,

View File

@@ -1,6 +1,7 @@
use crate::{
AngularVelocity, GameAssets,
event::BulletDestroy,
AngularVelocity, GameAssets, GameState, Lives,
asteroids::Asteroid,
event::{BulletDestroy, ShipDestroy},
physics::{Velocity, Wrapping},
};
@@ -44,3 +45,38 @@ pub fn bullet_impact_listener(mut commands: Commands, mut events: EventReader<Bu
commands.entity(event.0).despawn();
}
}
/// Watch for [`ShipDestroy`] events and update game state accordingly.
///
/// - Subtract a life
/// - Check life count. If 0, go to game-over state
/// - Clear all asteroids
/// - Respawn player
pub fn ship_impact_listener(
mut events: EventReader<ShipDestroy>,
mut commands: Commands,
mut lives: ResMut<Lives>,
rocks: Query<Entity, With<Asteroid>>,
mut player: Single<(&mut Transform, &mut Velocity), With<Ship>>,
mut next_state: ResMut<NextState<GameState>>,
) {
for _ in events.read() {
// STEP 1: Decrement lives (and maybe go to game over)
if lives.0 == 0 {
// If already at 0, game is over.
next_state.set(GameState::GameOver);
} else {
// Decrease life count.
lives.0 -= 1;
}
// STEP 2: Clear asteroids
for rock in rocks {
commands.entity(rock).despawn();
}
// STEP 3: Respawn player (teleport them to the origin)
player.0.translation = Vec3::ZERO;
player.1.0 = Vec2::ZERO;
}
}