diff --git a/src/bin/tetris/main.rs b/src/bin/tetris/main.rs index cc4598a..7ebd37d 100644 --- a/src/bin/tetris/main.rs +++ b/src/bin/tetris/main.rs @@ -9,16 +9,26 @@ fn main() { ..default() }) .add_systems(Startup, init_pieces) - .add_systems(Update, (kb_movement.run_if(on_event::), update_position)) + .add_systems( + Update, + ( + kb_movement.run_if(on_event::), + update_position, + update_orientation, + ), + ) .add_systems(Update, draw_grid) - .add_systems(Update, zoom_camera) .run(); } const SCALE: f32 = 30.0; #[derive(Component, Default, Debug, Clone, Copy)] -struct GridPosition { x: isize, y: isize } +#[require(Transform, Visibility)] +struct GridPosition { + x: isize, + y: isize, +} impl From<&GridPosition> for Vec3 { fn from(GridPosition { x, y }: &GridPosition) -> Vec3 { @@ -36,7 +46,51 @@ impl std::ops::Add for GridPosition { type Output = Self; fn add(self, GridPosition { x: x2, y: y2 }: Self) -> Self { - GridPosition { x: self.x + x2, y: self.y + y2 } + GridPosition { + x: self.x + x2, + y: self.y + y2, + } + } +} + +#[derive(Component, Default, Debug)] +enum Orientation { + #[default] + Up, + Left, + Down, + Right, +} + +impl Orientation { + fn next(&self) -> Self { + match self { + Self::Up => Self::Left, + Self::Left => Self::Down, + Self::Down => Self::Right, + Self::Right => Self::Up, + } + } + + fn prev(&self) -> Self { + match self { + Self::Up => Self::Right, + Self::Right => Self::Down, + Self::Down => Self::Left, + Self::Left => Self::Up, + } + } +} + +impl From<&Orientation> for Quat { + fn from(other: &Orientation) -> Quat { + let z = match other { + Orientation::Up => 0.0, + Orientation::Left => -PI * 0.5, + Orientation::Down => -PI, + Orientation::Right => -PI * 1.5, + }; + Quat::from_rotation_z(z) } } @@ -45,74 +99,83 @@ fn init_pieces( mut meshes: ResMut>, mut materials: ResMut>, ) { - commands.spawn(( - Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), - MeshMaterial2d(materials.add(ColorMaterial { - color: WHITE.into(), - ..default() - })), - Transform::default(), - GridPosition::default(), - )); + commands + .spawn((Orientation::default(), GridPosition::default())) + .with_children(|parent| { + let mat = materials.add(ColorMaterial { + color: WHITE.into(), + ..default() + }); + parent.spawn(( + Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), + MeshMaterial2d(mat.clone()), + Transform::from_xyz(0.0, 0.0, 0.0), + )); + parent.spawn(( + Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), + MeshMaterial2d(mat.clone()), + Transform::from_xyz(SCALE, 0.0, 0.0), + )); + parent.spawn(( + Mesh2d(meshes.add(Rectangle::new(SCALE, SCALE))), + MeshMaterial2d(mat.clone()), + Transform::from_xyz(0.0, SCALE, 0.0), + )); + }); } -fn update_position( - mut query: Query<(&GridPosition, &mut Transform), Changed>, -) { +fn update_position(mut query: Query<(&GridPosition, &mut Transform), Changed>) { query.iter_mut().for_each(|(gp, mut t)| { let tmp: Vec3 = gp.into(); - info!("Updating position {:?}", tmp); + debug!("Updating position {:?}", tmp); t.translation = gp.into(); }); } -fn kb_movement(mut events: EventReader, mut query: Query<&mut GridPosition>) { - events.read().for_each(|KeyboardInput { 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| { - info!("Moving by {:?}", diff); - *gp = *gp + diff; - }); - } +fn update_orientation(mut query: Query<(&Orientation, &mut Transform), Changed>) { + query.iter_mut().for_each(|(o, mut t)| { + t.rotation = o.into(); + debug!("Setting orientation to {:?}", o); }); } -fn draw_grid( - mut gizmos: Gizmos, -) { - gizmos.grid_2d( - Isometry2d::IDENTITY, - UVec2::new(10, 20), - Vec2::new(SCALE, SCALE), - GREEN - ).outer_edges(); +fn kb_movement(mut events: EventReader, mut query: Query<(&mut GridPosition, &mut Orientation)>) { + events.read().for_each( + |KeyboardInput { + 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; + }); + + if let KeyCode::Enter = key_code { + query.iter_mut().for_each(|(_, mut o)| { + *o = o.next(); + }); + } + } + }, + ); } -fn zoom_camera( - mut events: EventReader, - mut query: Single<&mut Transform, With>, -) { - events.read().for_each(|MouseWheel { unit, y, .. }| { - let movement = match unit { - MouseScrollUnit::Line => y * 1.0, - MouseScrollUnit::Pixel => y * 1.0, - }; - query.translation.z += movement; - }); +fn draw_grid(mut gizmos: Gizmos) { + gizmos + .grid_2d( + Isometry2d::IDENTITY, + UVec2::new(10, 20), + Vec2::new(SCALE, SCALE), + GREEN, + ) + .outer_edges(); }