From 3de04ab7587436b4bfb99ccfbe3c7fa0da98cf2f Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Fri, 1 Aug 2025 18:21:54 -0700 Subject: [PATCH] Flap button in UI works! Also moved flapping to observer --- src/bin/flappy/main.rs | 119 ++++++++++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 30 deletions(-) diff --git a/src/bin/flappy/main.rs b/src/bin/flappy/main.rs index 6a43d08..3b89106 100644 --- a/src/bin/flappy/main.rs +++ b/src/bin/flappy/main.rs @@ -17,6 +17,7 @@ fn main() { .init_resource::() .init_resource::() .init_resource::() + .init_resource::() .init_state::() .add_systems( Startup, @@ -52,7 +53,7 @@ fn main() { // Systems to run in the "play" state ( // Only flap when we press the space key - flap.run_if(input_just_pressed(KeyCode::Space)), + flap_kb.run_if(input_just_pressed(KeyCode::Space)), // Rewinding systems record.run_if(any_component_changed::), ) @@ -71,11 +72,13 @@ fn main() { ( sync_resource_to_ui::.run_if(resource_changed::), sync_resource_to_ui::.run_if(resource_changed::), + sync_resource_to_ui::.run_if(resource_changed::), sync_resource_to_ui::.run_if(resource_changed::), ), scoring.run_if(on_event::) ), ) + .add_observer(flap) .run(); } @@ -238,6 +241,7 @@ fn init_ui(mut commands: Commands) { (SyncResource::::default(), Text::default(), TextLayout::new_with_justify(JustifyText::Center)), (SyncResource::::default(), Text::default(), TextLayout::new_with_justify(JustifyText::Center)), (SyncResource::::default(), Text::default(), TextLayout::new_with_justify(JustifyText::Center)), + (SyncResource::::default(), Text::default(), TextLayout::new_with_justify(JustifyText::Center)), (Text::new("Press R to Rewind"), TextLayout::new_with_justify(JustifyText::Center)), ], )); @@ -261,27 +265,50 @@ fn init_ui(mut commands: Commands) { )) .observe(start_game); - fn start_rewind(trigger: Trigger>, mut next: ResMut>) { - next.set(PlayerState::Rewind); - } + commands.spawn( + Node { + align_self: AlignSelf::End, + justify_self: JustifySelf::Center, + flex_direction: FlexDirection::Row, + ..default() + }, + ).with_children(|parent| { + + parent + .spawn(( + Node { + ..default() + }, + Button, + children![Text::new("Rewind!"),], + )) + .observe(start_rewind) + .observe(end_rewind); + + parent + .spawn(( + Node { + ..default() + }, + Button, + children![Text::new("Flap!"),], + )) + .observe(flap_button); + }); +} - fn end_rewind(trigger: Trigger>, mut next: ResMut>) { - next.set(PlayerState::Alive); - } +fn start_rewind(_trigger: Trigger>, mut next: ResMut>) { + next.set(PlayerState::Rewind); +} - commands - .spawn(( - Node { - align_self: AlignSelf::End, - justify_self: JustifySelf::Center, - flex_direction: FlexDirection::Column, - ..default() - }, - Button, - children![Text::new("Rewind!"),], - )) - .observe(start_rewind) - .observe(end_rewind); +fn end_rewind(_trigger: Trigger>, mut next: ResMut>) { + next.set(PlayerState::Alive); +} + +fn flap_button(trigger: Trigger>, mut commands: Commands, bird: Single>) { + let e = *bird; + info!("Flapping {:?}", e); + commands.trigger_targets(Flap, e); } /// Pause the game when the player presses "Escape" @@ -296,12 +323,29 @@ fn un_pause_game(mut next: ResMut>) { // TODO: Create floor (and ceiling?) // Q: Move bird + camera or move world around bird & camera? // TODO: Obstacles +#[derive(Component, Clone, Event)] +struct Flap; -fn flap( +// Observer for flapping +fn flap(trigger: Trigger, + mut bird: Query<&mut ExternalImpulse, With>, + mut flaps: ResMut, + ) { + info!("real flap for {:?}", trigger.target()); + // Increment flap stat + flaps.0 += 1; + + // Flap birds wings + if let Ok(mut f) = bird.get_mut(trigger.target()) { + f.apply_impulse(Vec2::Y * 5000.0 + Vec2::X * 1000.0); + } +} + +fn flap_kb( #[cfg(debug_assertions)] state: Res>, #[cfg(debug_assertions)] keycode: Res>, - mut bird: Query<(&Transform, &mut ExternalImpulse), With>, - mut flaps: ResMut, + birds: Query>, + mut commands: Commands, ) { debug_assert!( matches!(state.get(), PlayerState::Alive), @@ -312,12 +356,9 @@ fn flap( "Only flap when space is just pressed" ); - // Increment flap stat - flaps.0 += 1; - - // Flap birds wings - bird.iter_mut().for_each(|(_, mut f)| { - f.apply_impulse(Vec2::Y * 5000.0 + Vec2::X * 1000.0); + birds.iter().for_each(|e| { + info!("Flapping {:?}", e); + commands.trigger_targets(Flap, e); }); } @@ -410,10 +451,18 @@ fn alive_bird( } fn pause_bird( - #[cfg(debug_assertions)] state: Res>, + state: Res>, mut bird: Single<&mut RigidBody, With>, + mut deaths: ResMut, ) { debug_assert!(!matches!(state.get(), PlayerState::Alive)); + + // Increment death count + match state.get() { + PlayerState::Stasis => deaths.0 += 1, + _ => (), + } + debug!("Setting bird to Static"); **bird = RigidBody::Static; } @@ -455,6 +504,16 @@ impl Display for Flaps { } } +// Track number of times player died +#[derive(Resource, Default)] +struct Deaths(usize); + +impl Display for Deaths { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + writeln!(f, "Deaths: {}", self.0) + } +} + fn scoring( mut events: EventReader, state: Res>,