diff --git a/src/bin/tetris/main.rs b/src/bin/tetris/main.rs index 29f7614..4f84866 100644 --- a/src/bin/tetris/main.rs +++ b/src/bin/tetris/main.rs @@ -42,13 +42,13 @@ fn main() { add_piece .run_if(not(any_with_component::)) .after(update_next_shapes), - update_shape_blocks - .run_if(any_component_added::.or(any_component_changed::)), falling .run_if(in_state(GameState::Falling)) .run_if(clock_cycle(1.0)), update_position.run_if(any_component_changed::), - deactivate_shape.run_if(any_component_removed::), + update_shape_blocks + .run_if(any_component_added::.or(any_component_changed::)).after(update_position), + deactivate_shape.run_if(any_component_removed::).after(update_shape_blocks), check_line_removal, // Clearing lines systems clear_line.run_if(any_component_changed::), @@ -565,6 +565,9 @@ fn kb_input( KeyCode::ArrowRight => { commands.entity(e).trigger(Movement::Right); } + KeyCode::Space => { + commands.entity(e).trigger(Movement::Skip); + } KeyCode::Escape => next.set(match curr.get() { GameState::Falling => GameState::Pause, GameState::Pause => GameState::Falling, @@ -705,6 +708,7 @@ enum Movement { Left, Right, Rotate, + Skip, } // TODO: When out of bounds left/right, try to move piece away from wall @@ -719,57 +723,66 @@ fn movement( shape.get_mut(trigger.target()), grid_positions.get(trigger.target()), ) { - let (new_center, new_shape) = match trigger.event() { - Movement::Down => (center.with_offset(0, -1), *this_shape), - Movement::Left => (center.with_offset(-1, 0), *this_shape), - Movement::Right => (center.with_offset(1, 0), *this_shape), - Movement::Rotate => (Ok(*center), this_shape.rotated()), + let new_positions = match trigger.event() { + Movement::Down => vec![center.with_offset(0, -1)], + Movement::Left => vec![center.with_offset(-1, 0)], + Movement::Right => vec![center.with_offset(1, 0)], + Movement::Rotate => vec![Ok(*center)], + Movement::Skip => (1..20).map(|i| center.with_offset(0, -i)).collect(), + }; + let new_shape = match trigger.event() { + Movement::Down | Movement::Left | Movement::Right | Movement::Skip => *this_shape, + Movement::Rotate => this_shape.rotated(), }; debug!( "Proposed change: {:?}\n{}", - new_center, + new_positions, new_shape.as_ascii() ); - match new_center { - Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => (), // Do nothing - Err(GameError::OutOfBoundsDown) => { - commands.entity(trigger.target()).remove::(); - } - Err(GameError::Collision) => panic!("This shouldn't happen!"), - Ok(new_center) => { - let new_blocks = new_shape.coordinates(&new_center); - for block_gp in new_blocks { - match block_gp { - Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => { - return; - } // Do nothing - Err(GameError::OutOfBoundsDown) => { - commands.entity(trigger.target()).remove::(); - return; - } - Err(GameError::Collision) => panic!("This shouldn't happen!"), - Ok(gp) => { - for other_gp in inactive.iter() { - // If there would be a collision between blocks - if gp == *other_gp { - // And we are moving down - if *trigger.event() == Movement::Down { - // De-activate this piece - commands.entity(trigger.target()).remove::(); + for position in new_positions { + match position { + Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => (), // Do nothing + Err(GameError::OutOfBoundsDown) => { + commands.entity(trigger.target()).remove::(); + } + Err(GameError::Collision) => panic!("This shouldn't happen!"), + Ok(new_center) => { + let new_blocks = new_shape.coordinates(&new_center); + for block_gp in new_blocks { + match block_gp { + Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => { + return; + } // Do nothing + Err(GameError::OutOfBoundsDown) => { + commands.entity(trigger.target()).remove::(); + return; + } + Err(GameError::Collision) => panic!("This shouldn't happen!"), + Ok(gp) => { + for other_gp in inactive.iter() { + // If there would be a collision between blocks + if gp == *other_gp { + // And we are moving down + if *trigger.event() == Movement::Down { + // De-activate this piece + commands.entity(trigger.target()).remove::(); + } + // Regardless, cancel the move + return; } - // Regardless, cancel the move - return; } } } } + info!("Checks passed for {position:?}, committing change"); + + // Update center + let mut gp = grid_positions.get_mut(trigger.target()).unwrap(); + *gp = new_center; + // Update shape/rotation + let mut s = shape.get_mut(trigger.target()).unwrap(); + *s = new_shape; } - // Update center - let mut gp = grid_positions.get_mut(trigger.target()).unwrap(); - *gp = new_center; - // Update shape/rotation - let mut s = shape.get_mut(trigger.target()).unwrap(); - *s = new_shape; } } } else {