From f89d52bfbf2e6427689703acabbd6aa6a07bbc43 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Tue, 7 Oct 2025 15:49:24 -0700 Subject: [PATCH] Add bounds checking for pieces --- src/bin/tetris/main.rs | 91 +++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/src/bin/tetris/main.rs b/src/bin/tetris/main.rs index 7ebd37d..1c85953 100644 --- a/src/bin/tetris/main.rs +++ b/src/bin/tetris/main.rs @@ -26,18 +26,49 @@ const SCALE: f32 = 30.0; #[derive(Component, Default, Debug, Clone, Copy)] #[require(Transform, Visibility)] struct GridPosition { - x: isize, - y: isize, + x: usize, + y: usize, +} + +// 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_down(&mut self) { + self.y = self.y.saturating_sub(1); + } + + fn move_left(&mut self) { + self.x = self.x.saturating_sub(1); + } + + fn move_right(&mut self) { + if self.x + 1 < 10 { + self.x = self.x.saturating_add(1); + } + } } impl From<&GridPosition> for Vec3 { fn from(GridPosition { x, y }: &GridPosition) -> Vec3 { - Vec3::new((*x as f32) * SCALE, (*y as f32) * SCALE, 0.0) + // Grid Positions start in the bottom left of the area + // So (0, 0) is the bottom left, (0, 9) is the bottom right, etc + + let x_0 = -SCALE * 5.0 + (0.5 * SCALE); + let x = x_0 + ((*x as f32) * SCALE); + + let y_0 = -SCALE * 10.0 + (0.5 * SCALE); + let y = y_0 + ((*y as f32) * SCALE); + Vec3::new(x, y, 0.0) } } -impl From<(isize, isize)> for GridPosition { - fn from((x, y): (isize, isize)) -> GridPosition { +impl From<(usize, usize)> for GridPosition { + fn from((x, y): (usize, usize)) -> GridPosition { GridPosition { x, y } } } @@ -53,6 +84,12 @@ impl std::ops::Add for GridPosition { } } +impl std::ops::AddAssign<&GridPosition> for GridPosition { + fn add_assign(&mut self, rhs: &GridPosition) { + *self = *self + *rhs; + } +} + #[derive(Component, Default, Debug)] enum Orientation { #[default] @@ -106,30 +143,34 @@ fn init_pieces( color: WHITE.into(), ..default() }); + let mesh = meshes.add(Rectangle::new(SCALE, SCALE)); parent.spawn(( - Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), + Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), Transform::from_xyz(0.0, 0.0, 0.0), )); parent.spawn(( - Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), + Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), Transform::from_xyz(SCALE, 0.0, 0.0), )); parent.spawn(( - Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), + Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), Transform::from_xyz(0.0, SCALE, 0.0), )); + parent.spawn(( + Mesh2d(mesh.clone()), + MeshMaterial2d(mat.clone()), + Transform::from_xyz(-SCALE, 0.0, 0.0), + )); }); } fn update_position(mut query: Query<(&GridPosition, &mut Transform), Changed>) { query.iter_mut().for_each(|(gp, mut t)| { - let tmp: Vec3 = gp.into(); - debug!("Updating position {:?}", tmp); - t.translation = gp.into(); + debug!("Updating position {:?}", t.translation); }); } @@ -146,24 +187,18 @@ fn kb_movement(mut events: EventReader, mut query: Query<(&mut Gr key_code, state, .. }| { if let ButtonState::Pressed = state { - let diff: GridPosition = match key_code { - KeyCode::ArrowUp => (0, 1), - KeyCode::ArrowDown => (0, -1), - KeyCode::ArrowLeft => (-1, 0), - KeyCode::ArrowRight => (1, 0), - _ => (0, 0), - } - .into(); - query.iter_mut().for_each(|(mut gp, _)| { - debug!("Moving by {:?}", diff); - *gp = *gp + diff; + // TODO: Restict movement based on size/orientation of piece + // 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::Enter => *o = o.next(), + _ => () + } }); - - if let KeyCode::Enter = key_code { - query.iter_mut().for_each(|(_, mut o)| { - *o = o.next(); - }); - } } }, );