Added piece type component

master
hheik 2025-08-20 15:13:42 +03:00
parent 946bcfb246
commit 381609c261
4 changed files with 57 additions and 21 deletions

View File

@ -21,6 +21,8 @@ pub fn init(app: &mut App) {
.register_type::<tetris::Piece>() .register_type::<tetris::Piece>()
.register_type::<tetris::PieceControls>() .register_type::<tetris::PieceControls>()
.register_type::<tetris::ControllablePiece>() .register_type::<tetris::ControllablePiece>()
.register_type::<tetris::Block>()
.register_type::<prefab::PieceType>()
.register_type::<grid::Grid>() .register_type::<grid::Grid>()
.register_type::<grid::GridTransform>() .register_type::<grid::GridTransform>()
.add_systems(Startup, systems::setup_game_scene) .add_systems(Startup, systems::setup_game_scene)

View File

@ -17,10 +17,12 @@ use super::{PIXEL_SCALE, grid::*, tetris::*};
)] )]
pub struct DemoCamera2d; pub struct DemoCamera2d;
#[derive(Clone, Copy, Debug, Reflect)] #[derive(Component, Clone, Copy, Debug, Default, Reflect)]
#[reflect(Component)]
pub enum PieceType { pub enum PieceType {
/// ...... /// ......
/// .XXXX. /// .XXXX.
#[default]
I, I,
/// ..X.. /// ..X..
/// .XXX. /// .XXX.
@ -105,9 +107,11 @@ impl PieceType {
} }
} }
pub fn create_block(pos: Vector2I, color: Color) -> impl Bundle { pub fn create_block(pos: impl Into<Vector2I>, color: Color) -> impl Bundle {
( (
GridTransform::from_xy(pos.x, pos.y), GridTransform {
translation: pos.into(),
},
Block, Block,
create_block_sprite(color), create_block_sprite(color),
) )
@ -127,17 +131,18 @@ pub fn create_block_sprite(color: Color) -> impl Bundle {
) )
} }
pub fn create_piece(piece: PieceType) -> impl Bundle { pub fn create_piece(piece_type: PieceType) -> impl Bundle {
let pos_arr = piece.block_positions(); let pos_arr = piece_type.block_positions();
let mut pos_iter = pos_arr.iter(); let mut pos_iter = pos_arr.iter();
( (
Name::from(piece.name()), Name::from(piece_type.name()),
Piece, Piece,
piece_type,
children![ children![
create_block(*pos_iter.next().unwrap(), piece.color()), create_block(*pos_iter.next().unwrap(), piece_type.color()),
create_block(*pos_iter.next().unwrap(), piece.color()), create_block(*pos_iter.next().unwrap(), piece_type.color()),
create_block(*pos_iter.next().unwrap(), piece.color()), create_block(*pos_iter.next().unwrap(), piece_type.color()),
create_block(*pos_iter.next().unwrap(), piece.color()), create_block(*pos_iter.next().unwrap(), piece_type.color()),
], ],
) )
} }

View File

@ -94,7 +94,7 @@ pub fn apply_piece_movement(
// TODO: replace with actual logic // TODO: replace with actual logic
if piece_controls.instant_drop { if piece_controls.instant_drop {
grid_transform.translation.y = 0; grid_transform.translation.y = 0;
on_piece_placed.write(OnPiecePlaced { entity }); on_piece_placed.write(OnPiecePlaced { piece: entity });
*input_repeat = None; *input_repeat = None;
continue; continue;
} }
@ -105,7 +105,7 @@ pub fn apply_piece_movement(
} }
if !can_move_down && piece_controls.cumulated_gravity >= 3.0 { if !can_move_down && piece_controls.cumulated_gravity >= 3.0 {
// Force piece placement // Force piece placement
on_piece_placed.write(OnPiecePlaced { entity }); on_piece_placed.write(OnPiecePlaced { piece: entity });
*input_repeat = None; *input_repeat = None;
continue; continue;
} }
@ -152,17 +152,19 @@ pub fn handle_piece_placed(
mut on_piece_placed: EventReader<OnPiecePlaced>, mut on_piece_placed: EventReader<OnPiecePlaced>,
mut commands: Commands, mut commands: Commands,
parent_query: Query<&ChildOf>, parent_query: Query<&ChildOf>,
child_query: Query<&Children>,
grid_transform_query: Query<&GridTransform>,
block_query: Query<&GridTransform, With<Block>>,
mut next_piece_query: Query<(&mut NextPiece, &GameArea)>, mut next_piece_query: Query<(&mut NextPiece, &GameArea)>,
) { ) {
for event in on_piece_placed.read() { for OnPiecePlaced { piece } in on_piece_placed.read() {
info!("Placed piece {:#}", event.entity); let piece = *piece;
let mut entity_cmds = commands
.get_entity(event.entity) let parent = parent_query.get(piece).unwrap().0;
.unwrap()
.remove::<(PieceControls, ControllablePiece)>();
let parent = parent_query.get(event.entity).unwrap().0;
let (mut next_piece, game_area) = next_piece_query.get_mut(parent).unwrap(); let (mut next_piece, game_area) = next_piece_query.get_mut(parent).unwrap();
let new_piece = next_piece.take_and_generate(); let new_piece = next_piece.take_and_generate();
// Create new piece
commands.entity(parent).with_child(( commands.entity(parent).with_child((
GridTransform { GridTransform {
translation: game_area.block_spawn_point(), translation: game_area.block_spawn_point(),
@ -170,6 +172,33 @@ pub fn handle_piece_placed(
ControllablePiece, ControllablePiece,
create_piece(new_piece), create_piece(new_piece),
)); ));
// Move blocks from old piece to under game area
let piece_position = grid_transform_query.get(piece).cloned().unwrap_or_default();
for child in child_query
.get(piece)
.iter()
.flat_map(|children| children.iter())
{
if let Ok(block_pos) = block_query.get(child) {
let global_pos = piece_position.translation + block_pos.translation;
commands.entity(child).insert((
GridTransform {
translation: global_pos,
},
ChildOf(parent),
));
}
}
// Despawn old piece
commands.entity(piece).despawn();
// commands
// .get_entity(event.entity)
// .unwrap()
// .remove::<(PieceControls, ControllablePiece)>();
// TODO: Finish up clearing the piece / lines // TODO: Finish up clearing the piece / lines
// TODO: Lose condition // TODO: Lose condition
} }

View File

@ -123,11 +123,11 @@ impl NextPiece {
} }
} }
#[derive(Component, Clone, Debug, Reflect)] #[derive(Component, Clone, Debug, Default, Reflect)]
#[reflect(Component)] #[reflect(Component)]
pub struct Block; pub struct Block;
#[derive(Event, Clone, Debug)] #[derive(Event, Clone, Debug)]
pub struct OnPiecePlaced { pub struct OnPiecePlaced {
pub entity: Entity, pub piece: Entity,
} }