diff --git a/Cargo.toml b/Cargo.toml index 8570b1f..3ec4a3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,4 @@ bevy_kira_audio = { version = "0.8", features = ["wav"] } heron = { version = "2.0.1", features = ["2d", "enhanced-determinism"] } bevy-inspector-egui = "0.8" rand = "0.8" +derive_more = "0.99" \ No newline at end of file diff --git a/src/history.rs b/src/history.rs new file mode 100644 index 0000000..9074047 --- /dev/null +++ b/src/history.rs @@ -0,0 +1,86 @@ +use bevy::{ + core::FixedTimestep, + input::{keyboard::KeyboardInput, ElementState}, + prelude::*, +}; +use derive_more::{Deref, DerefMut}; +use heron::{RigidBody, Velocity}; + +use crate::GameState; + +#[derive(Component, Deref, DerefMut, Default)] +pub struct PositionHistory(Vec); + +#[derive(Component, Deref, DerefMut, Default)] +pub struct RewindState(bool); + +pub struct RewindPlugin; + +impl Plugin for RewindPlugin { + fn build(&self, app: &mut App) { + app.add_system_set( + SystemSet::on_update(GameState::Playing) + .with_run_criteria(FixedTimestep::steps_per_second(20.0)) + .with_system(add_trackers) + .with_system(detect_rewind) + .with_system(tick_position_trackers), + ) + .insert_resource(RewindState(false)) + .add_system_set( + SystemSet::on_update(GameState::Playing) + .with_run_criteria(FixedTimestep::steps_per_second(60.0)) + .with_system(rewind_system), + ); + } +} + +pub fn add_trackers( + mut commands: Commands, + entities: Query, With, Without)>, +) { + for entity in entities.iter() { + commands.entity(entity).insert(PositionHistory::default()); + } +} + +pub fn tick_position_trackers( + mut query: Query<(&mut PositionHistory, &Transform)>, + rewind_state: Res, +) { + if rewind_state.0 { + return; + } + for (mut history, transform) in query.iter_mut() { + history.push(transform.translation); + } +} + +pub fn detect_rewind(mut input: EventReader, mut game_state: ResMut) { + for ev in input.iter() { + if ev.key_code == Some(KeyCode::Space) && ev.state.is_pressed() { + println!("triggering rewind"); + game_state.0 = true; + } + } +} + +pub fn rewind_system( + mut query: Query<(&mut PositionHistory, &mut Transform)>, + mut game_state: ResMut, +) { + if !game_state.0 { + return; + } + let mut history_left = false; + for (mut history, mut transform) in query.iter_mut() { + if let Some(position) = history.pop() { + history_left = true; + *transform = Transform::from_translation(position); + println!("{} iters left", history.len()); + } + } + if !history_left { + println!("done with rewind"); + game_state.0 = false; + } +} diff --git a/src/main.rs b/src/main.rs index 58a20be..2c8b6fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ use resources::audio_channels::AudioChannels; mod enemy; pub mod gun; +mod history; mod inputs; mod item; mod levels; @@ -50,6 +51,7 @@ fn main() { .add_plugin(item::ItemPlugin) .add_plugin(gun::GunPlugin) .add_plugin(enemy::EnemyPlugin) + .add_plugin(history::RewindPlugin) .add_state(GameState::MainMenu) .run(); }