|
|
|
@ -31,6 +31,8 @@ fn main() {
|
|
|
|
(
|
|
|
|
(
|
|
|
|
// Only flap when we press the space key
|
|
|
|
// Only flap when we press the space key
|
|
|
|
flap.run_if(input_just_pressed(KeyCode::Space)),
|
|
|
|
flap.run_if(input_just_pressed(KeyCode::Space)),
|
|
|
|
|
|
|
|
// Rewinding systems
|
|
|
|
|
|
|
|
record.run_if(any_component_changed::<Transform>),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.run_if(in_state(PlayerState::Alive)),
|
|
|
|
.run_if(in_state(PlayerState::Alive)),
|
|
|
|
// Rewinding systems
|
|
|
|
// Rewinding systems
|
|
|
|
@ -51,6 +53,13 @@ enum PlayerState {
|
|
|
|
Dead,
|
|
|
|
Dead,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// A tape tracking the bird's state every frame
|
|
|
|
|
|
|
|
#[derive(Component, Default)]
|
|
|
|
|
|
|
|
struct Tape {
|
|
|
|
|
|
|
|
translations: Vec<Vec3>,
|
|
|
|
|
|
|
|
rotations: Vec<Quat>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn init_bird(
|
|
|
|
fn init_bird(
|
|
|
|
mut commands: Commands,
|
|
|
|
mut commands: Commands,
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
@ -74,7 +83,9 @@ fn init_bird(
|
|
|
|
|
|
|
|
|
|
|
|
let force = ExternalForce::default().with_persistence(false);
|
|
|
|
let force = ExternalForce::default().with_persistence(false);
|
|
|
|
|
|
|
|
|
|
|
|
commands.spawn((name, mesh, material, mass, t, Bird, force));
|
|
|
|
let tape = Tape::default();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
commands.spawn((name, mesh, material, mass, t, Bird, force, tape));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn init_ui(
|
|
|
|
fn init_ui(
|
|
|
|
@ -133,17 +144,33 @@ fn toggle_rewind(keycode: Res<ButtonInput<KeyCode>>, mut next: ResMut<NextState<
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn record(
|
|
|
|
|
|
|
|
#[cfg(debug_assertions)] state: Res<State<PlayerState>>,
|
|
|
|
|
|
|
|
mut birds: Query<(&Transform, &mut Tape), With<Bird>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
debug_assert!(
|
|
|
|
|
|
|
|
matches!(state.get(), PlayerState::Alive),
|
|
|
|
|
|
|
|
"Only record in the alive state"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
birds.iter_mut().for_each(|(transform, mut tape)| {
|
|
|
|
|
|
|
|
tape.translations.push(transform.translation);
|
|
|
|
|
|
|
|
tape.rotations.push(transform.rotation);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn rewind(
|
|
|
|
fn rewind(
|
|
|
|
#[cfg(debug_assertions)] state: Res<State<PlayerState>>,
|
|
|
|
#[cfg(debug_assertions)] state: Res<State<PlayerState>>,
|
|
|
|
birds: Query<&Transform, With<Bird>>,
|
|
|
|
mut birds: Query<(&mut Transform, &mut Tape), With<Bird>>,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
debug_assert!(
|
|
|
|
debug_assert!(
|
|
|
|
matches!(state.get(), PlayerState::Rewind),
|
|
|
|
matches!(state.get(), PlayerState::Rewind),
|
|
|
|
"Only rewind in the rewinding state"
|
|
|
|
"Only rewind in the rewinding state"
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
birds.iter().for_each(|bird| {
|
|
|
|
birds.iter_mut().for_each(|(mut transform, mut tape)| {
|
|
|
|
info!("Position: {:?}", *bird);
|
|
|
|
transform.translation = tape.translations.pop().unwrap();
|
|
|
|
|
|
|
|
transform.rotation = tape.rotations.pop().unwrap();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|