diff --git a/src/fruit.rs b/src/fruit.rs index 36ce882..132bf27 100644 --- a/src/fruit.rs +++ b/src/fruit.rs @@ -20,7 +20,7 @@ impl Plugin for FruitPlugin { ) .add_system(debug_eaten_event_system) .add_system(despawn_fruit_system) - .add_system(spawn_fruit_system.run_on_event::()); + .add_system(spawn_fruit_system.run_if(eaten_event_sent)); } } @@ -29,6 +29,10 @@ pub struct EatenEvent(Option); #[derive(Component)] pub struct Fruit; +fn eaten_event_sent(mut eaten_event_reader: EventReader) -> bool { + eaten_event_reader.iter().count() != 0 +} + fn spawn_fruit_system(mut commands: Commands) { // TODO: not spawn in snake let mut rng = rand::thread_rng(); diff --git a/src/snake.rs b/src/snake.rs index 56a1b96..f839ba3 100644 --- a/src/snake.rs +++ b/src/snake.rs @@ -3,12 +3,10 @@ use bevy::prelude::*; use itertools::Itertools; use iyes_loopless::prelude::*; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[derive(StageLabel)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, StageLabel)] struct MovementStage; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[derive(SystemLabel)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, SystemLabel)] pub enum SystemLabel { SegmentMovement, } @@ -37,11 +35,16 @@ impl Plugin for SnakePlugin { .run_if(tick_triggered) .after(SystemLabel::SegmentMovement), ) + .add_system( + update_direction_system + .run_in_state(AppState::InGame) + .run_if(tick_triggered), + ) .add_system( game_over_system .run_in_state(AppState::InGame) - .run_if(about_to_lose) - .run_if(tick_triggered), + .run_if(tick_triggered) + .run_if(about_to_lose), ) .add_system(add_direction_system.run_in_state(AppState::Begin)) .add_system(change_direction_system.run_in_state(AppState::InGame)) @@ -66,6 +69,9 @@ enum Direction { Right, } +#[derive(Component)] +struct DirectionBuffer(Option); + #[derive(Component)] struct Snake; @@ -116,7 +122,8 @@ fn setup_snake_system(mut commands: Commands) { commands .entity(snake_head) .insert(Name::new("SnakeHead")) - .insert(SnakeHead); + .insert(SnakeHead) + .insert(DirectionBuffer(None)); commands .spawn() @@ -160,22 +167,33 @@ fn add_tail_system( } } +fn update_direction_system( + mut query: Query<(&mut Direction, &mut DirectionBuffer), With>, +) { + for (mut direction, mut direction_buffer) in query.iter_mut() { + if let Some(new_direction) = direction_buffer.0 { + *direction = new_direction; + direction_buffer.0 = None; + } + } +} + fn change_direction_system( keypress: Res>, - mut query: Query<&mut Direction, With>, + mut query: Query<(&Direction, &mut DirectionBuffer), With>, ) { if let Some(new_direction) = Direction::from_keypress(keypress) { - let mut direction = query.single_mut(); + let (direction, mut direction_buffer) = query.single_mut(); - match (direction.as_ref(), &new_direction) { - (Direction::Up, Direction::Down) - | (Direction::Down, Direction::Up) - | (Direction::Left, Direction::Right) - | (Direction::Right, Direction::Left) => return, - _ => {} + if let (Direction::Up, Direction::Down) + | (Direction::Down, Direction::Up) + | (Direction::Left, Direction::Right) + | (Direction::Right, Direction::Left) = (direction, &new_direction) + { + return; } - *direction = new_direction; + direction_buffer.0 = Some(new_direction); } } diff --git a/src/tick.rs b/src/tick.rs index df0e11e..c0c1289 100644 --- a/src/tick.rs +++ b/src/tick.rs @@ -5,8 +5,7 @@ use std::time::Duration; const TICK_PERIOD: u64 = 125; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[derive(StageLabel)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, StageLabel)] struct FixedTimeStage; pub struct TickPlugin; @@ -16,14 +15,12 @@ impl Plugin for TickPlugin { let mut fixed_time_system_stage = SystemStage::parallel(); fixed_time_system_stage.add_system(tick_event_system.run_in_state(AppState::InGame)); - app.add_event::() - .add_stage_before( - CoreStage::Update, - FixedTimeStage, - FixedTimestepStage::new(Duration::from_millis(TICK_PERIOD)) - .with_stage(fixed_time_system_stage), - ); - // .add_system(print_tick_system); + app.add_event::().add_stage_before( + CoreStage::Update, + FixedTimeStage, + FixedTimestepStage::new(Duration::from_millis(TICK_PERIOD)) + .with_stage(fixed_time_system_stage), + ); } } @@ -36,9 +33,3 @@ fn tick_event_system(mut event_writer: EventWriter) { pub fn tick_triggered(mut event_reader: EventReader) -> bool { event_reader.iter().count() != 0 } - -// fn print_tick_system(mut event_reader: EventReader) { -// for _ in event_reader.iter() { -// println!("Tick"); -// } -// }