From 7ef5a7370457e0fa076056fa0e0d33f8d790e15b Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Sat, 18 Oct 2025 22:30:03 -0700 Subject: [PATCH] not perfect, but gooder movement --- src/bin/tetris/main.rs | 255 ++++++++++++++++++++--------------------- 1 file changed, 123 insertions(+), 132 deletions(-) diff --git a/src/bin/tetris/main.rs b/src/bin/tetris/main.rs index 554612f..43f4364 100644 --- a/src/bin/tetris/main.rs +++ b/src/bin/tetris/main.rs @@ -21,7 +21,6 @@ fn main() { Update, ( kb_input.run_if(on_event::), - update_position, falling .run_if(in_state(Falling::On)) .run_if(clock_cycle(1.0)), @@ -31,19 +30,16 @@ fn main() { .or(any_component_added::) .or(any_component_changed::), ), - shape_block_movement.run_if( - any_component_added:: - .or(any_component_changed::) - .or(any_component_changed::), - ), + update_relative_position, + update_position.after(update_relative_position), sync_singleton_to_ui::.run_if(any_component_changed::), sync_singleton_to_ui::.run_if(any_component_changed::), - check_collision.run_if(any_component_changed::), add_piece.run_if(not(any_with_component::)), clear_line.run_if(any_component_changed::), ), ) .add_systems(Update, draw_grid) + .add_observer(deactive_shape) .run(); } @@ -115,7 +111,7 @@ struct Line(u8); #[derive(Component, Debug)] struct Block; -#[derive(Component, Event, Debug)] +#[derive(Component, Event, Debug, Clone, Copy)] #[require(GridPosition)] struct RelativePosition { x: i8, @@ -124,31 +120,19 @@ struct RelativePosition { impl RelativePosition { fn up() -> Self { - RelativePosition { - x: 0, - y: 1, - } + RelativePosition { x: 0, y: 1 } } fn down() -> Self { - RelativePosition { - x: 0, - y: -1, - } + RelativePosition { x: 0, y: -1 } } fn left() -> Self { - RelativePosition { - x: -1, - y: 0, - } + RelativePosition { x: -1, y: 0 } } fn right() -> Self { - RelativePosition { - x: 1, - y: 0, - } + RelativePosition { x: 1, y: 0 } } } @@ -206,12 +190,23 @@ impl GridPosition { self.x == other.x && self.y.saturating_sub(1) == other.y } - fn add_offset(&self, RelativePosition { x: x1, y: y1 }: &RelativePosition) -> Result { - let x = self.x.checked_add_signed(*x1 as i32).ok_or(GameError::OutOfBoundsLeft)?; - let y = self.y.checked_add_signed(*y1 as i32).ok_or(GameError::OutOfBoundsDown)?; - if x >= X_MAX { // TODO: y > Y_MAX? + fn add_relative( + &self, + RelativePosition { x: x1, y: y1 }: &RelativePosition, + ) -> Result { + let x = self + .x + .checked_add_signed(*x1 as i32) + .ok_or(GameError::OutOfBoundsLeft)?; + let y = self + .y + .checked_add_signed(*y1 as i32) + .ok_or(GameError::OutOfBoundsDown)?; + if x >= X_MAX { + // TODO: y > Y_MAX? Err(GameError::OutOfBoundsRight) } else { + debug!("Moving to {x},{y}"); Ok(GridPosition { x, y }) } } @@ -514,7 +509,7 @@ fn set_piece( visuals: Res, ) { query.iter().for_each(|(e, s, o)| { - debug!("{e:?} {s:?} {o:?}"); + debug!("Setting piece: {e:?} {s:?} {o:?}"); let mesh = visuals.mesh.clone(); let mat = visuals.material.clone(); @@ -525,7 +520,9 @@ fn set_piece( .entity(e) .with_related_entities::(|parent| { positions.into_iter().for_each(|rp| { - parent.spawn((Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), rp, Block)); + parent + .spawn((Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), rp, Block)) + .observe(movement); }); }); } else { @@ -537,11 +534,42 @@ fn set_piece( }); } -fn update_position(mut query: Query<(&GridPosition, &mut Transform), Changed>) { - query.iter_mut().for_each(|(gp, mut t)| { +fn update_position( + mut changed: Query< + (Entity, &GridPosition, &mut Transform), + Or<(Added, Changed)>, + >, +) { + changed.iter_mut().for_each(|(e, gp, mut t)| { + let v3: Vec3 = gp.into(); + debug!( + "Updating {e} with grid position {:?} to coordinates {:?}", + gp, v3 + ); + debug_assert!(gp.x < X_MAX, "block x > x_max"); t.translation = gp.into(); - debug!("Updating position {:?}", t.translation); + }); +} + +fn update_relative_position( + shape: Single<&GridPosition, With>, + mut query: Query< + (Entity, &mut GridPosition, &RelativePosition), + ( + Without, + Or<(Added, Changed)>, + ), + >, +) { + query.iter_mut().for_each(|(e, mut gp, rp)| { + debug!( + "Updating {e} grid position to {:?} + {:?} = {:?}", + gp, + rp, + gp.add_relative(rp).unwrap() + ); + *gp = (*shape).add_relative(rp).unwrap(); }); } @@ -568,13 +596,13 @@ fn kb_input( } KeyCode::ArrowDown => { commands.entity(e).trigger(RelativePosition::down()); - }, + } KeyCode::ArrowLeft => { commands.entity(e).trigger(RelativePosition::left()); - }, + } KeyCode::ArrowRight => { commands.entity(e).trigger(RelativePosition::right()); - }, + } KeyCode::Space => next.set(match curr.get() { Falling::On => Falling::Off, Falling::Off => Falling::On, @@ -607,28 +635,11 @@ fn draw_grid(mut gizmos: Gizmos) { fn falling(mut shape: Query>, mut commands: Commands) { shape.iter_mut().for_each(|e| { + info!("Making {:?} fall", e); commands.entity(e).trigger(RelativePosition::down()); }); } -// Re-implement parenting for movement, but on the grid structure -fn shape_block_movement( - shape: Query< - &GridPosition, - ( - With, - Without, - ), - >, - mut blocks: Query<(&mut GridPosition, &RelativePosition), With>, -) { - shape.iter().for_each(|shape_gp| { - blocks.iter_mut().for_each(|(mut block_gp, block_rp)| { - *block_gp = shape_gp.add_offset(block_rp).expect("Cannot move there..."); - }); - }); -} - // Run condition that returns `true` every `n` seconds // TODO: Update a resource with the current tick fn clock_cycle(n: f32) -> impl FnMut(Res