diff --git a/src/bin/tetris/main.rs b/src/bin/tetris/main.rs index 1c85953..bc8b9c4 100644 --- a/src/bin/tetris/main.rs +++ b/src/bin/tetris/main.rs @@ -8,6 +8,7 @@ fn main() { game_type: GameType::Two, ..default() }) + .init_state::() .add_systems(Startup, init_pieces) .add_systems( Update, @@ -15,6 +16,8 @@ fn main() { kb_movement.run_if(on_event::), update_position, update_orientation, + toggle_falling.run_if(on_event::), + falling.run_if(in_state(Falling::On)).run_if(clock_cycle(1.0)) ), ) .add_systems(Update, draw_grid) @@ -23,7 +26,7 @@ fn main() { const SCALE: f32 = 30.0; -#[derive(Component, Default, Debug, Clone, Copy)] +#[derive(Component, Default, Debug, Clone, Copy, PartialEq)] #[require(Transform, Visibility)] struct GridPosition { x: usize, @@ -32,23 +35,31 @@ struct GridPosition { // TODO: Restirct movement to within the grid impl GridPosition { - fn move_up(&mut self) { - if self.y + 1 < 20 { - self.y = self.y.saturating_add(1); + fn move_up(&self) -> Self { + Self { + y: if self.y + 1 < 20 { self.y.saturating_add(1) } else { self.y }, + x: self.x } } - fn move_down(&mut self) { - self.y = self.y.saturating_sub(1); + fn move_down(&mut self) -> Self { + Self { + y: self.y.saturating_sub(1), + x: self.x + } } - fn move_left(&mut self) { - self.x = self.x.saturating_sub(1); + fn move_left(&mut self) -> Self { + Self { + x: self.x.saturating_sub(1), + y: self.y + } } - fn move_right(&mut self) { - if self.x + 1 < 10 { - self.x = self.x.saturating_add(1); + fn move_right(&mut self) -> Self { + Self { + x: if self.x + 1 < 10 { self.x.saturating_add(1) } else { self.x }, + y: self.y } } } @@ -131,6 +142,13 @@ impl From<&Orientation> for Quat { } } +#[derive(States, Clone, Eq, PartialEq, Debug, Hash, Default, Component)] +enum Falling { + #[default] + On, + Off +} + fn init_pieces( mut commands: Commands, mut meshes: ResMut>, @@ -191,10 +209,10 @@ fn kb_movement(mut events: EventReader, mut query: Query<(&mut Gr // Check if children would be outside play area... query.iter_mut().for_each(|(mut gp, mut o)| { match key_code { - KeyCode::ArrowUp => gp.move_up(), - KeyCode::ArrowDown => gp.move_down(), - KeyCode::ArrowLeft => gp.move_left(), - KeyCode::ArrowRight => gp.move_right(), + KeyCode::ArrowUp => *gp = gp.move_up(), + KeyCode::ArrowDown => *gp = gp.move_down(), + KeyCode::ArrowLeft => *gp = gp.move_left(), + KeyCode::ArrowRight => *gp = gp.move_right(), KeyCode::Enter => *o = o.next(), _ => () } @@ -214,3 +232,44 @@ fn draw_grid(mut gizmos: Gizmos) { ) .outer_edges(); } + +fn toggle_falling( + mut events: EventReader, + curr: Res>, + mut next: ResMut>, +) { + events.read().for_each(|KeyboardInput { state, key_code, .. }| { + if let ButtonState::Pressed = state && *key_code == KeyCode::Space { + next.set(match curr.get() { + Falling::On => Falling::Off, + Falling::Off => Falling::On, + }); + } + }) +} + +fn falling( + mut query: Query<&mut GridPosition> +) { + query.iter_mut ().for_each(|mut gp| { + let next = gp.move_down(); + if next != *gp { + *gp = next; + } else { + // Remove the falling component from this entity + } + }); +} + +// Run condition that returns `true` every `n` seconds +fn clock_cycle(n: f32) -> impl FnMut (Res