diff --git a/src/bin/flappy/main.rs b/src/bin/flappy/main.rs index 41e0d70..2d61e70 100644 --- a/src/bin/flappy/main.rs +++ b/src/bin/flappy/main.rs @@ -1,8 +1,6 @@ // Bevy basically forces "complex types" with Querys #![allow(clippy::type_complexity)] -use bevy::platform::hash::RandomState; -use std::hash::BuildHasher; use games::physics2d::*; use games::*; @@ -82,6 +80,7 @@ fn main() { sync_resource_to_ui::.run_if(resource_changed::), ), scoring.run_if(on_event::), + create_forward_batches.run_if(on_event::).run_if(in_state(PlayerState::Alive)), ), ) .add_observer(flap) @@ -194,24 +193,29 @@ fn init_first_batches( fn populate_batch( trigger: Trigger, batches: Query<&Batch>, + children: Query<&ChildOf>, mut commands: Commands, ) { - let Batch(batch_id) = batches.get(trigger.target()).unwrap(); - commands - .entity(trigger.target()) - .insert((Transform::from_xyz(500.0 * (*batch_id) as f32, 0.0, 0.0), Visibility::Inherited)) - .with_children(|parent| { - parent.spawn(Ground(-2)); - parent.spawn(Ground(-1)); - parent.spawn(Ground(0)); - parent.spawn(Ground(1)); - parent.spawn(Ground(2)); - if *batch_id > 0 { - parent.spawn(Pipe::Top); - parent.spawn(Pipe::Bottom); - parent.spawn(Hitbox); - } - }); + // Only run this for top level batch entities, + // not children containing a reference to their batch, like hitboxes + if !children.contains(trigger.target()) { + let Batch(batch_id) = batches.get(trigger.target()).unwrap(); + commands + .entity(trigger.target()) + .insert((Transform::from_xyz(500.0 * (*batch_id) as f32, 0.0, 0.0), Visibility::Inherited)) + .with_children(|parent| { + parent.spawn(Ground(-2)); + parent.spawn(Ground(-1)); + parent.spawn(Ground(0)); + parent.spawn(Ground(1)); + parent.spawn(Ground(2)); + if *batch_id > 0 { + parent.spawn(Pipe::Top); + parent.spawn(Pipe::Bottom); + parent.spawn((Hitbox, Batch(*batch_id))); + } + }); + } } /// The ground population spawns a center peace and two pieces of ground @@ -648,3 +652,32 @@ fn scoring( } }) } + +/// When the player moves forward while alive +/// spawn more batches and despawn old batches +fn create_forward_batches( + mut events: EventReader, + state: Res>, + bird: Query>, + hitboxes: Query<&Batch, With>, + batches: Query<(Entity, &Batch), (With, Without)>, + mut commands: Commands, +) { + debug_assert!(*state.get() == PlayerState::Alive); + events + .read() + .filter(|CollisionStarted(a, b)| bird.contains(*a) && hitboxes.contains(*b)) + .for_each(|CollisionStarted(_, b)| { + let Batch(idx) = hitboxes.get(*b).unwrap(); + info!("Batch {:?}", idx); + if *idx > 2 { + // Spawn future batch + commands.spawn(Batch(idx + 2)); + + // Despawn old batch + if let Some((despawn_batch, _)) = batches.iter().find(|(_, Batch(n))| *n == idx - 2) { + commands.entity(despawn_batch).despawn(); + } + } + }); +}