From 467f81bee7902a273ef1a4abe590a724bcb6a3fa Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Sun, 14 Dec 2025 22:21:49 -0800 Subject: [PATCH] Hey basic movement works! Some stuff does not but it's a hard panic so we WILL find it. --- tetris/src/blocks.rs | 153 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 141 insertions(+), 12 deletions(-) diff --git a/tetris/src/blocks.rs b/tetris/src/blocks.rs index ec4bcc1..12e4279 100644 --- a/tetris/src/blocks.rs +++ b/tetris/src/blocks.rs @@ -1,3 +1,5 @@ +#![allow(clippy::type_complexity)] + use super::*; // TODO: @@ -33,15 +35,24 @@ impl Plugin for BlocksPlugin { fn build(&self, app: &mut App) { app.init_asset::() .init_asset_loader::() + .add_message::() .add_systems(OnEnter(Loading(true)), load_assets.run_if(run_once)) .add_systems(OnEnter(GameState::Setup), (setup_camera, setup_blocks)) .add_systems( Update, - updated_shape_asset.run_if(on_message::>), + ( + updated_shape_asset.run_if(on_message::>), + update_grid_position.run_if( + any_component_added:: + .or(any_component_changed::), + ), + propogate_grid_position.run_if(any_component_changed::), + handle_kb_input.run_if(on_message::), + handle_movement.run_if(on_message::), + ), ) .add_observer(add_shape) - .add_observer(add_relative_position) - .add_observer(add_grid_position); + .add_observer(add_relative_position); } } @@ -78,13 +89,13 @@ impl ShapeAsset { (self.mesh.clone(), self.material.clone(), b), (self.mesh.clone(), self.material.clone(), c), (self.mesh.clone(), self.material.clone(), d), - ]) + ]), ) } } /// The main play area grid coordinates -#[derive(Component)] +#[derive(Component, Debug, Clone)] #[require(Transform)] struct GridPosition { pub x: usize, @@ -108,6 +119,31 @@ impl Into for &GridPosition { } } +impl std::ops::AddAssign for GridPosition { + fn add_assign(&mut self, rhs: RelativePosition) { + self.x = self.x.strict_add_signed(rhs.x); + self.y = self.y.strict_add_signed(rhs.y); + } +} + +impl std::ops::SubAssign for GridPosition { + fn sub_assign(&mut self, rhs: RelativePosition) { + self.x = self.x.strict_sub_signed(rhs.x); + self.y = self.y.strict_sub_signed(rhs.y); + } +} + +impl std::ops::Add for GridPosition { + type Output = GridPosition; + + fn add(self, rhs: RelativePosition) -> GridPosition { + GridPosition { + x: self.x.strict_add_signed(rhs.x), + y: self.y.strict_add_signed(rhs.y), + } + } +} + /// Block positions relative to the shape's center #[derive(Component, PartialEq, Debug, Clone, Copy)] pub(crate) struct RelativePosition { @@ -115,9 +151,15 @@ pub(crate) struct RelativePosition { pub y: isize, } +impl RelativePosition { + fn new(x: isize, y: isize) -> Self { + RelativePosition { x, y } + } +} + impl From<(isize, isize)> for RelativePosition { fn from((x, y): (isize, isize)) -> Self { - RelativePosition { x, y } + RelativePosition::new(x, y) } } @@ -294,13 +336,100 @@ fn add_relative_position( let parent_shape = blocks.get(event.entity).unwrap(); let rp = relative_positions.get(event.entity).unwrap(); let gp = grid_positions.get(parent_shape.0).unwrap(); - commands.entity(event.entity).insert(gp.with_relative_offset(rp)); + commands + .entity(event.entity) + .insert(gp.with_relative_offset(rp)); } -fn add_grid_position( - event: On, - mut query: Query<(&GridPosition, &mut Transform)>, +/// Populate Transform when GridPosition is added to an entity +fn update_grid_position( + mut query: Query< + (&GridPosition, &mut Transform), + Or<(Added, Changed)>, + >, ) { - let (gp, mut t) = query.get_mut(event.entity).unwrap(); - t.translation = gp.into(); + query.iter_mut().for_each(|(gp, mut t)| { + info!("Updating grid position to {:?}", gp); + t.translation = gp.into(); + }); +} + +fn propogate_grid_position( + parent: Query<(&GridPosition, &ShapeBlocks), Changed>, + mut children: Query<(&mut GridPosition, &RelativePosition), Without>, +) { + parent.iter().for_each(|(parent_gp, sbs)| { + sbs.iter().for_each(|e| { + let (mut gp, rp) = children.get_mut(e).unwrap(); + *gp = parent_gp.clone() + *rp; + }); + }); +} + +/// Movement message used to propose/plan a move +#[derive(Debug, Message)] +enum Movement { + Rotate, + Left, + Down, + Right, +} + +/// Handle KeyBoard input +/// Nothing is handled directly in this method, +/// All key presses result in either a message, event, or state change +fn handle_kb_input(mut input: MessageReader, mut moves: MessageWriter) { + input.read().for_each( + |KeyboardInput { + key_code, state, .. + }| { + if *state == ButtonState::Pressed { + match key_code { + KeyCode::ArrowLeft => { + moves.write(Movement::Left); + } + KeyCode::ArrowRight => { + moves.write(Movement::Right); + } + KeyCode::ArrowDown => { + moves.write(Movement::Down); + } + KeyCode::ArrowUp => { + moves.write(Movement::Rotate); + } + KeyCode::Escape => todo!("Pause Toggle"), + _ => (), // Do nothing + }; + } + }, + ); +} + +fn handle_movement( + mut moves: MessageReader, + mut query: Query<&mut GridPosition, With>, +) { + moves.read().for_each(|m| match m { + Movement::Left => { + query.iter_mut().for_each(|mut gp| { + info!("moving shape left"); + *gp -= RelativePosition::new(1, 0); + }); + } + Movement::Right => { + query.iter_mut().for_each(|mut gp| { + info!("moving shape right"); + *gp += RelativePosition::new(1, 0); + }); + } + Movement::Down => { + query.iter_mut().for_each(|mut gp| { + info!("moving shape down"); + *gp -= RelativePosition::new(0, 1); + }); + } + Movement::Rotate => { + todo!() + } + }) }