diff --git a/src/bin/flappy/main.rs b/src/bin/flappy/main.rs index d0d02f3..e7fc7b6 100644 --- a/src/bin/flappy/main.rs +++ b/src/bin/flappy/main.rs @@ -1,9 +1,9 @@ // Bevy basically forces "complex types" with Querys #![allow(clippy::type_complexity)] -use std::hash::BuildHasher; use games::physics2d::*; use games::*; +use std::hash::BuildHasher; fn main() { App::new() @@ -35,9 +35,9 @@ fn main() { ), ) .add_systems(OnEnter(PlayerState::Alive), alive_bird) + .add_systems(OnEnter(PlayerState::Rewind), alive_bird) .add_systems(OnEnter(PlayerState::Pause), pause_bird) .add_systems(OnEnter(PlayerState::Stasis), pause_bird) - // .add_systems(OnEnter(PlayerState::Rewind), pause_bird) .add_systems( Update, ( @@ -84,21 +84,16 @@ fn main() { update_batch_position.run_if(any_component_changed::), update_tooltip.run_if(in_state(DebuggingState::On)), // TODO: Add run_if to this system - manage_batches, - ( - // Temp debugging systems - debug_collision_events.run_if(on_event::), - ), + hitbox_collision_handler, + // TODO: Add run_if to this system + manage_score, ), ) - .add_observer(debug_collision_start_observations) - .add_observer(debug_collision_end_observations) .add_observer(flap) .add_observer(populate_batch) .add_observer(populate_pipe) .add_observer(populate_ground) .add_observer(populate_hitbox) - .add_observer(manage_score) .run(); } @@ -275,7 +270,7 @@ fn populate_pipe( pipes: Query<(&Pipe, &Batch)>, pipe_assets: Res, mut commands: Commands, - rand: Res + rand: Res, ) { let pipe_t = { let (pipe, Batch(id)) = pipes.get(trigger.target()).unwrap(); @@ -294,8 +289,12 @@ fn populate_pipe( }; match pipe { - Pipe::Top => Transform::from_xyz(0.0, 200.0 + offset, -1.0).with_scale(Vec3::splat(100.0)), - Pipe::Bottom => Transform::from_xyz(0.0, -100.0 + offset, -1.0).with_scale(Vec3::splat(100.0)), + Pipe::Top => { + Transform::from_xyz(0.0, 200.0 + offset, -1.0).with_scale(Vec3::splat(100.0)) + } + Pipe::Bottom => { + Transform::from_xyz(0.0, -100.0 + offset, -1.0).with_scale(Vec3::splat(100.0)) + } } }; commands.entity(trigger.target()).insert(( @@ -447,14 +446,22 @@ fn init_ui(mut commands: Commands) { ..default() }, PlayerState::Credits, - children![(Text::new(credits_str), TextLayout::new_with_justify(JustifyText::Center))], + children![( + Text::new(credits_str), + TextLayout::new_with_justify(JustifyText::Center) + )], )) .with_children(|parent| { - parent.spawn((Node { - align_self: AlignSelf::Center, - ..default() - }, Button, children![Text::new("Close")])); - }).observe(hide_credits); + parent.spawn(( + Node { + align_self: AlignSelf::Center, + ..default() + }, + Button, + children![Text::new("Close")], + )); + }) + .observe(hide_credits); fn start_game(_trigger: Trigger>, mut next: ResMut>) { next.set(PlayerState::Alive); @@ -635,6 +642,7 @@ fn record( fn rewind( #[cfg(debug_assertions)] state: Res>, + mut next: ResMut>, mut birds: Query< ( &mut AccumulatedTranslation, @@ -660,7 +668,10 @@ fn rewind( birds.iter_mut().for_each( |(mut at, mut lv, mut av, mut eai, mut ef, mut ei, mut et, mut p, mut r, mut tape)| { - if !tape.positions.is_empty() { + if tape.positions.is_empty() { + next.set(PlayerState::Pause); + } else { + // TODO: Only record/restore variables that we manage! at.0 = tape.accumulated_translations.pop().unwrap().0; lv.0 = tape.linear_velocities.pop().unwrap().0; av.0 = tape.angular_velocities.pop().unwrap().0; @@ -701,12 +712,8 @@ fn detect_dead( } fn alive_bird( - #[cfg(debug_assertions)] state: Res>, mut bird: Single<&mut RigidBody, With>, ) { - #[cfg(debug_assertions)] - debug_assert!(matches!(state.get(), PlayerState::Alive)); - debug!("Setting bird to Dynamic"); **bird = RigidBody::Dynamic; } @@ -716,8 +723,6 @@ fn pause_bird( mut bird: Single<&mut RigidBody, With>, mut deaths: ResMut, ) { - debug_assert!(!matches!(state.get(), PlayerState::Alive)); - // Increment death count if state.get() == &PlayerState::Stasis { deaths.0 += 1 @@ -775,65 +780,45 @@ impl Display for Deaths { } fn manage_score( - trigger: Trigger, + mut start: EventReader, + mut end: EventReader, state: Res>, - bird: Query>, hitboxes: Query<&Batch, With>, mut score: ResMut, ) { - let a = trigger.target(); - let b = trigger.collider; - if bird.contains(a) && hitboxes.contains(b) { - debug!("Hit event while {:?}", state.get()); - let Batch(id) = hitboxes.get(b).unwrap(); - score.0 = match state.get() { - PlayerState::Alive => *id, - PlayerState::Rewind => *id - 1, - _ => *id, // HOW??? + match state.get() { + PlayerState::Rewind => { + start.read().for_each(|CollisionStarted(a, b)| { + // Set score to collided hitbox + if let Ok(Batch(this)) = hitboxes.get(*a) + { + info!("[Rewind] Setting score to {this}"); + score.0 = this - 1; + } else if let Ok(Batch(this)) = hitboxes.get(*b) { + info!("[Rewind] Setting score to {this}"); + score.0 = this - 1; + } + }) + } + _ => { + end.read().for_each(|CollisionEnded(a, b)| { + // Set score to collided hitbox + if let Ok(Batch(this)) = hitboxes.get(*b) + { + info!("[Alive] Setting score to {this}"); + score.0 = *this; + } else if let Ok(Batch(this)) = hitboxes.get(*a) { + info!("[Alive] Setting score to {this}"); + score.0 = *this; + } + }) } } } -fn debug_collision_events( - mut end: EventReader, - mut start: EventReader, - state: Res>, -) { - start.read().for_each(|CollisionStarted(a, b)| { - debug!("Collision started between {a} and {b} in {:?}", state.get()); - }); - end.read().for_each(|CollisionEnded(a, b)| { - debug!("Collision ended between {a} and {b} in {:?}", state.get()); - }); -} - -fn debug_collision_start_observations( - trigger: Trigger, - state: Res>, -) { - debug!( - "Collision started between {} and {} in {:?}", - trigger.target(), - trigger.collider, - state.get() - ); -} - -fn debug_collision_end_observations( - trigger: Trigger, - state: Res>, -) { - debug!( - "Collision end between {} and {} in {:?}", - trigger.target(), - trigger.collider, - state.get() - ); -} - /// When the player moves forward while alive /// spawn more batches and despawn old batches -fn manage_batches( +fn hitbox_collision_handler( bird: Query<&ColliderAabb, With>, hitboxes: Query<(Entity, &ColliderAabb), With>, batches: Query<(Entity, &Batch)>, @@ -841,23 +826,24 @@ fn manage_batches( mut commands: Commands, ) { bird.iter().for_each(|bird_aabb| { - if let Some(e) = hitboxes.iter().find_map(|(e, hitbox_aabb)| { - bird_aabb.intersects(hitbox_aabb).then_some(e) - }) { + if let Some(e) = hitboxes + .iter() + .find_map(|(e, hitbox_aabb)| bird_aabb.intersects(hitbox_aabb).then_some(e)) + { let (_, Batch(curr)) = batches.get(e).unwrap(); let (target_batch_id, new_batch_id) = match state.get() { PlayerState::Alive => (curr.saturating_sub(2), curr.saturating_add(2)), PlayerState::Rewind => (curr.saturating_add(2), curr.saturating_sub(2)), _ => (*curr, *curr), }; - if target_batch_id == 0 || new_batch_id == 0 { - // skip - } else { - if target_batch_id != new_batch_id { - if let Some(e_old) = batches.iter().find_map(|(e, b)| (b.0 == target_batch_id).then_some(e)) { - commands.entity(e_old).insert(Batch(new_batch_id)); - } - } + if target_batch_id > 0 + && new_batch_id > 0 + && target_batch_id != new_batch_id + && let Some(e_old) = batches + .iter() + .find_map(|(e, b)| (b.0 == target_batch_id).then_some(e)) + { + commands.entity(e_old).insert(Batch(new_batch_id)); } }; });