|
|
|
|
@ -80,11 +80,12 @@ fn main() {
|
|
|
|
|
sync_resource_to_ui::<RewindFrames>.run_if(resource_changed::<RewindFrames>),
|
|
|
|
|
),
|
|
|
|
|
scoring.run_if(on_event::<CollisionEnded>),
|
|
|
|
|
create_forward_batches.run_if(on_event::<CollisionStarted>).run_if(in_state(PlayerState::Alive)),
|
|
|
|
|
manage_batches.run_if(on_event::<CollisionStarted>).run_if(in_state(PlayerState::Alive).or(in_state(PlayerState::Rewind))),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
.add_observer(flap)
|
|
|
|
|
.add_observer(populate_batch)
|
|
|
|
|
.add_observer(update_batch)
|
|
|
|
|
.add_observer(populate_pipe)
|
|
|
|
|
.add_observer(populate_ground)
|
|
|
|
|
.add_observer(populate_hitbox)
|
|
|
|
|
@ -218,6 +219,17 @@ fn populate_batch(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn update_batch(
|
|
|
|
|
trigger: Trigger<OnReplace, Batch>,
|
|
|
|
|
mut root: Query<(&mut Transform, &Batch), With<Children>>,
|
|
|
|
|
) {
|
|
|
|
|
if let Ok((mut t, Batch(idx))) = root.get_mut(trigger.target()) {
|
|
|
|
|
info!("Updating batch {:?}", idx);
|
|
|
|
|
t.translation.x = 500.0 * (*idx) as f32;
|
|
|
|
|
}
|
|
|
|
|
// todo!("Adjust pipe positions");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The ground population spawns a center peace and two pieces of ground
|
|
|
|
|
/// to the left and right of the center.
|
|
|
|
|
fn populate_ground(
|
|
|
|
|
@ -227,12 +239,13 @@ fn populate_ground(
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
let Ground(idx) = grounds.get(trigger.target()).unwrap();
|
|
|
|
|
info!("populating ground {:?}", idx);
|
|
|
|
|
commands.entity(trigger.target()).insert((
|
|
|
|
|
ground_assets.material.clone(),
|
|
|
|
|
ground_assets.mesh.clone(),
|
|
|
|
|
Name::new("ground"),
|
|
|
|
|
RigidBody::Static, Collider::rectangle(1.0, 1.0),
|
|
|
|
|
Transform::from_xyz(100.0 * (*idx) as f32, -400.0, -1.0).with_scale(Vec3::splat(100.0))
|
|
|
|
|
Transform::from_xyz(100.0 * (*idx) as f32, -300.0, -1.0).with_scale(Vec3::splat(100.0))
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -655,29 +668,33 @@ fn scoring(
|
|
|
|
|
|
|
|
|
|
/// When the player moves forward while alive
|
|
|
|
|
/// spawn more batches and despawn old batches
|
|
|
|
|
fn create_forward_batches(
|
|
|
|
|
fn manage_batches(
|
|
|
|
|
mut events: EventReader<CollisionStarted>,
|
|
|
|
|
state: Res<State<PlayerState>>,
|
|
|
|
|
bird: Query<Entity, With<Bird>>,
|
|
|
|
|
hitboxes: Query<&Batch, With<Hitbox>>,
|
|
|
|
|
batches: Query<(Entity, &Batch), (With<Children>, Without<Hitbox>)>,
|
|
|
|
|
batches: Query<(Entity, &Batch)>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
debug_assert!(*state.get() == PlayerState::Alive);
|
|
|
|
|
debug_assert!(matches!(state.get(), PlayerState::Alive) || matches!(state.get(), PlayerState::Rewind));
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// This is written in a wonky way to avoid borrow checker rules
|
|
|
|
|
// Instaed of updating the Batch in place we use Commands to get it and upsert a new batch
|
|
|
|
|
.filter_map(|CollisionStarted(a, b)| {
|
|
|
|
|
if bird.contains(*a) && let Ok((e, Batch(idx))) = batches.get(*b) && *idx > 2 {
|
|
|
|
|
Some((e, idx))
|
|
|
|
|
} else { None }
|
|
|
|
|
}).for_each(|(_, idx)| {
|
|
|
|
|
let (old_batch_idx, new_batch_idx) = match state.get() {
|
|
|
|
|
PlayerState::Alive => (idx - 2, idx + 2),
|
|
|
|
|
PlayerState::Rewind => (idx + 2, idx - 2),
|
|
|
|
|
_ => panic!("Should not happen!"),
|
|
|
|
|
};
|
|
|
|
|
// Find all entities with the old batch and adjust them
|
|
|
|
|
batches.iter().filter_map(|(e, batch)| {
|
|
|
|
|
(batch.0 == old_batch_idx).then_some(e)
|
|
|
|
|
}).for_each(|e| {
|
|
|
|
|
commands.entity(e).insert(Batch(new_batch_idx));
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|