Compare commits
3 Commits
364fbd7530
...
45b1fe751f
| Author | SHA1 | Date | |
|---|---|---|---|
| 45b1fe751f | |||
| 3d28d489b0 | |||
| cdd665cc93 |
@@ -7,17 +7,31 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{GameAssets, Lifetime, WorldSize, config::ASTEROID_LIFETIME, physics::Velocity};
|
use crate::{
|
||||||
|
GameAssets, Lifetime, WorldSize, config::ASTEROID_LIFETIME, event::AsteroidDestroy,
|
||||||
|
physics::Velocity,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Component, Deref, DerefMut)]
|
#[derive(Component, Deref, DerefMut)]
|
||||||
pub struct Asteroid(AsteroidSize);
|
pub struct Asteroid(AsteroidSize);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum AsteroidSize {
|
pub enum AsteroidSize {
|
||||||
Small,
|
Small,
|
||||||
Medium,
|
Medium,
|
||||||
Large,
|
Large,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsteroidSize {
|
||||||
|
fn next(&self) -> Option<Self> {
|
||||||
|
match self {
|
||||||
|
AsteroidSize::Small => None,
|
||||||
|
AsteroidSize::Medium => Some(AsteroidSize::Small),
|
||||||
|
AsteroidSize::Large => Some(AsteroidSize::Medium),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct AsteroidSpawner {
|
pub struct AsteroidSpawner {
|
||||||
rng: std::sync::Mutex<rand::rngs::StdRng>,
|
rng: std::sync::Mutex<rand::rngs::StdRng>,
|
||||||
@@ -117,7 +131,7 @@ pub fn spawn_asteroid(
|
|||||||
};
|
};
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Asteroid(AsteroidSize::Small),
|
Asteroid(spawn.size),
|
||||||
Collider::ball(collider_radius),
|
Collider::ball(collider_radius),
|
||||||
Sensor,
|
Sensor,
|
||||||
Transform::from_translation(spawn.pos.extend(0.0)),
|
Transform::from_translation(spawn.pos.extend(0.0)),
|
||||||
@@ -128,3 +142,43 @@ pub fn spawn_asteroid(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Event listener for asteroid destruction events. Shrinks and multiplies
|
||||||
|
/// asteroids until they vanish.
|
||||||
|
///
|
||||||
|
/// - Large -> 2x Medium
|
||||||
|
/// - Medium -> 2x Small
|
||||||
|
/// - Small -> (despawned)
|
||||||
|
///
|
||||||
|
/// The velocity of the child asteroids is scattered somewhat, as if they were
|
||||||
|
/// explosively pushed apart.
|
||||||
|
pub fn split_asteroids(
|
||||||
|
mut destroy_events: EventReader<AsteroidDestroy>,
|
||||||
|
mut respawn_events: EventWriter<SpawnAsteroid>,
|
||||||
|
mut commands: Commands,
|
||||||
|
query: Query<(&Transform, &Asteroid, &Velocity)>,
|
||||||
|
) {
|
||||||
|
for event in destroy_events.read() {
|
||||||
|
if let Ok((transform, rock, velocity)) = query.get(event.0) {
|
||||||
|
let next_size = rock.0.next();
|
||||||
|
if let Some(size) = next_size {
|
||||||
|
let pos = transform.translation.xy();
|
||||||
|
let left_offset = Vec2::from_angle(0.4);
|
||||||
|
let right_offset = Vec2::from_angle(-0.4);
|
||||||
|
respawn_events.write(SpawnAsteroid {
|
||||||
|
pos,
|
||||||
|
vel: left_offset.rotate(velocity.0),
|
||||||
|
size,
|
||||||
|
});
|
||||||
|
respawn_events.write(SpawnAsteroid {
|
||||||
|
pos,
|
||||||
|
vel: right_offset.rotate(velocity.0),
|
||||||
|
size,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Always despawn the asteroid. New ones (may) be spawned in it's
|
||||||
|
// place, but this one is gone.
|
||||||
|
commands.entity(event.0).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ impl Plugin for AsteroidPlugin {
|
|||||||
physics::wrap_entities,
|
physics::wrap_entities,
|
||||||
asteroids::tick_asteroid_manager,
|
asteroids::tick_asteroid_manager,
|
||||||
asteroids::spawn_asteroid.after(asteroids::tick_asteroid_manager),
|
asteroids::spawn_asteroid.after(asteroids::tick_asteroid_manager),
|
||||||
|
asteroids::split_asteroids,
|
||||||
|
ship::bullet_impact_listener,
|
||||||
collision_listener,
|
collision_listener,
|
||||||
// TODO: Remove debug printing
|
// TODO: Remove debug printing
|
||||||
debug_collision_event_printer,
|
debug_collision_event_printer,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
AngularVelocity, GameAssets,
|
AngularVelocity, GameAssets,
|
||||||
|
event::BulletDestroy,
|
||||||
physics::{Velocity, Wrapping},
|
physics::{Velocity, Wrapping},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,3 +36,11 @@ pub fn spawn_player(mut commands: Commands, game_assets: Res<GameAssets>) {
|
|||||||
.with_translation(Vec3::new(-0.5, 0.0, -0.1)),
|
.with_translation(Vec3::new(-0.5, 0.0, -0.1)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Watch for [`BulletDestroy`] events and despawn
|
||||||
|
/// the associated bullet.
|
||||||
|
pub fn bullet_impact_listener(mut commands: Commands, mut events: EventReader<BulletDestroy>) {
|
||||||
|
for event in events.read() {
|
||||||
|
commands.entity(event.0).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user