From f68b052f2d1040d523fa41467d616b2e6d39b3c0 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Sat, 26 Jul 2025 14:30:52 -0700 Subject: [PATCH] Added ground --- src/base_game.rs | 3 +- src/bin/flappy/main.rs | 87 ++++++++++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/base_game.rs b/src/base_game.rs index 4c16399..a9e3ed8 100644 --- a/src/base_game.rs +++ b/src/base_game.rs @@ -47,6 +47,7 @@ pub fn toggle_state_visibility( }); } +// TODO: Rename to "create camera" pub fn setup_camera(mut commands: Commands) { - commands.spawn((Camera3d { ..default() }, Camera { ..default() })); + commands.spawn((Camera3d { ..default() }, Camera { ..default() }, AmbientLight::default())); } diff --git a/src/bin/flappy/main.rs b/src/bin/flappy/main.rs index 2789a6e..37f86a2 100644 --- a/src/bin/flappy/main.rs +++ b/src/bin/flappy/main.rs @@ -7,7 +7,7 @@ fn main() { name: "flappy bird (with rewind)".into(), }) .init_state::() - .add_systems(Startup, (init_bird, init_ui)) + .add_systems(Startup, (init_bird, init_ground, init_ui, tweak_camera.after(setup_camera))) .add_systems(OnEnter(PlayerState::Alive), alive_bird) .add_systems(OnExit(PlayerState::Alive), kill_bird) .add_systems( @@ -42,6 +42,15 @@ fn main() { .run(); } +fn tweak_camera( + mut camera: Query<(&mut Camera, &mut AmbientLight), With>, +) { + camera.iter_mut().for_each(|(mut c, mut al)| { + c.clear_color = ClearColorConfig::Custom(WHITE.into()); + al.brightness = 100.0; + }); +} + #[derive(Component)] struct Bird; @@ -68,7 +77,7 @@ fn init_bird( ) { let material = MeshMaterial3d(materials.add(StandardMaterial { base_color_texture: Some(server.load("flappy/bevy.png")), - base_color: WHITE.with_alpha(0.9).into(), + base_color: WHITE.into(), alpha_mode: AlphaMode::Blend, ..default() })); @@ -79,13 +88,40 @@ fn init_bird( let t = Transform::from_xyz(0.0, 0.0, -10.0).with_rotation(Quat::from_rotation_x(PI / 2.0)); - let mass = (RigidBody::Dynamic, Collider::capsule(1.0, 1.0), Mass(1.0)); - - let force = ExternalForce::default().with_persistence(false); + let physics = ( + RigidBody::Dynamic, + Collider::capsule(1.0, 1.0), Mass(1.0), + ExternalForce::default().with_persistence(false), + LockedAxes::ROTATION_LOCKED.lock_translation_z(), + ); let tape = Tape::default(); - commands.spawn((name, mesh, material, mass, t, Bird, force, tape)); + commands.spawn((name, mesh, material, physics, t, Bird, tape)); +} + +#[derive(Component)] +struct Ground; + +fn init_ground( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + let material = MeshMaterial3d(materials.add(StandardMaterial { + base_color: GREEN.into(), + ..default() + })); + + let mesh = Mesh3d(meshes.add(Cuboid::new(5.0, 1.0, 1.0))); + + let name = Name::new("ground"); + + let t = Transform::from_xyz(0.0, -4.0, -10.0); + + let physics = (RigidBody::Static, Collider::cuboid(1.0, 1.0, 1.0)); + + commands.spawn((name, mesh, material, physics, t, Ground)); } fn init_ui( @@ -125,7 +161,7 @@ fn flap( ); bird.iter_mut().for_each(|(t, mut f)| { - f.apply_force(t.rotation * Vec3::NEG_Z * 1000.0); + f.apply_force(t.rotation * Vec3::NEG_Z * 500.0); }); } @@ -135,7 +171,7 @@ fn toggle_rewind(keycode: Res>, mut next: ResMut>, - bird: Single>, - visible: Query<&VisibleEntities, With>, + bird: Single<&ColliderAabb, With>, + ground: Single<&ColliderAabb, With>, mut next: ResMut>, ) { debug_assert!( matches!(state.get(), PlayerState::Alive), "Only check if dead while alive" ); - visible.iter().for_each(|ve| { - if ve.entities.iter().len() > 0 { - let bird_visible = ve - .entities - .iter() - .any(|(_type_id, list)| list.contains(&(*bird))); - - if bird_visible { - debug!("Bird is visible, making alive"); - next.set(PlayerState::Alive); - } else { - debug!("Bird is not visible, making dead"); - next.set(PlayerState::Dead); - } - } - }); + if bird.intersects(*ground) { + next.set(PlayerState::Dead); + } } fn alive_bird( #[cfg(debug_assertions)] state: Res>, - bird: Single>, - mut commands: Commands, + mut bird: Single<&mut RigidBody, With>, ) { debug_assert!(!matches!(state.get(), PlayerState::Dead)); debug!("Aliving bird"); - commands.entity(*bird).insert(RigidBody::Dynamic); + **bird = RigidBody::Dynamic; } fn kill_bird( #[cfg(debug_assertions)] state: Res>, - bird: Single>, - mut commands: Commands, + mut bird: Single<&mut RigidBody, With>, ) { - debug_assert!(matches!(state.get(), PlayerState::Dead)); + debug_assert!(!matches!(state.get(), PlayerState::Alive)); debug!("Killing bird"); - commands.entity(*bird).remove::(); + **bird = RigidBody::Static; }