Adjusted the piece origins so they rotate better. Added some positional adjusting to make space for rotated pieces.

master
hheik 2025-08-23 13:17:41 +03:00
parent 0433a1f90b
commit 779f7b6dde
2 changed files with 29 additions and 24 deletions

View File

@ -17,7 +17,7 @@ use super::{PIXEL_SCALE, grid::*, tetris::*};
)]
pub struct DemoCamera2d;
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
#[derive(Component, Clone, Copy, Debug, Default, PartialEq, Eq, Reflect)]
#[reflect(Component)]
pub enum PieceType {
/// ......
@ -59,27 +59,17 @@ impl PieceType {
pub fn block_positions(&self) -> [Vector2I; 4] {
match self {
Self::I => [(0, 0), (1, 0), (2, 0), (3, 0)],
Self::T => [(0, 0), (1, 0), (1, 1), (2, 0)],
Self::L => [(0, 0), (1, 0), (2, 0), (2, 1)],
Self::J => [(0, 0), (0, 1), (1, 0), (2, 0)],
Self::S => [(0, 0), (1, 0), (1, 1), (2, 1)],
Self::Z => [(1, 0), (1, 1), (0, 1), (2, 0)],
Self::I => [(-1, 0), (0, 0), (1, 0), (2, 0)],
Self::T => [(-1, 0), (0, 0), (0, 1), (1, 0)],
Self::L => [(-1, 0), (0, 0), (1, 0), (1, 1)],
Self::J => [(-1, 0), (-1, 1), (0, 0), (1, 0)],
Self::S => [(-1, 0), (0, 0), (0, 1), (1, 1)],
Self::Z => [(-1, 1), (0, 0), (0, 1), (1, 0)],
Self::Square => [(0, 0), (0, 1), (1, 0), (1, 1)],
}
.map(|pos| pos.into())
}
// pub fn width(&self) -> i32 {
// let x_positions: Vec<_> = self.block_positions().iter().map(|pos| pos.x).collect();
// if x_positions.is_empty() {
// return 0;
// }
// let min = x_positions.iter().min().unwrap();
// let max = x_positions.iter().max().unwrap();
// max - min + 1
// }
pub fn name(&self) -> String {
match self {
Self::I => "I-piece",

View File

@ -1,7 +1,7 @@
use bevy::prelude::*;
use crate::{
game::{grid::*, tetris::*},
game::{grid::*, prefab::*, tetris::*},
util::Vector2I,
};
@ -21,9 +21,11 @@ pub fn apply_gravity(
}
}
#[allow(clippy::type_complexity)]
pub fn apply_piece_movement(
mut piece_query: Query<(
&PieceControls,
Option<&PieceType>,
Option<&mut Gravity>,
Entity,
&ChildOf,
@ -33,7 +35,9 @@ pub fn apply_piece_movement(
mut transform_query: Query<(&mut GridTransform, Has<Block>)>,
mut commands: Commands,
) {
for (controls, maybe_gravity, entity, parent, children) in piece_query.iter_mut() {
'piece_loop: for (controls, maybe_piece_type, maybe_gravity, entity, parent, children) in
piece_query.iter_mut()
{
let game_entity = parent.parent();
let (collisions, game_area) = game_query.get(game_entity).unwrap();
@ -99,6 +103,10 @@ pub fn apply_piece_movement(
}
{
// Skip rotating square piece
if maybe_piece_type.is_some_and(|piece_type| *piece_type == PieceType::Square) {
continue;
}
let cast_shape = |pos, blocks| {
collisions.cast_shape(pos, blocks) || !game_area.is_shape_inside(pos, blocks)
};
@ -113,9 +121,14 @@ pub fn apply_piece_movement(
.collect::<Vec<Vector2I>>()
};
let piece_pos = transform_query.get(entity).unwrap().0.translation;
if let Some(rotation) = controls.rotation {
let offsets = vec![(0, 0), (1, 0), (-1, 0), (2, 0), (-2, 0)];
let rotated = rotate_slice(&blocks, rotation);
if !cast_shape(piece_pos, &rotated) {
for offset in offsets {
if !cast_shape(piece_pos + offset.into(), &rotated) {
transform_query.get_mut(entity).unwrap().0.translation =
piece_pos + offset.into();
for child in children.iter() {
if let Ok((mut transform, has_block)) = transform_query.get_mut(child) {
if has_block {
@ -123,6 +136,8 @@ pub fn apply_piece_movement(
}
}
}
continue 'piece_loop;
}
}
}
}