We did it chat. We got clearing lines working

main
Elijah Voigt 2 days ago
parent a13aa62a1f
commit 90a6181e22

@ -15,6 +15,7 @@ path = "examples/demos/parallax3d.rs"
hide_debug = [] hide_debug = []
[dependencies] [dependencies]
itertools = "*"
thiserror = "2.0.12" thiserror = "2.0.12"
[dependencies.serde] [dependencies.serde]

@ -1,10 +1,9 @@
// Bevy basically forces "complex types" with Querys // Bevy basically forces "complex types" with Querys
#![allow(clippy::type_complexity)] #![allow(clippy::type_complexity)]
use itertools::Itertools;
use games::*; use games::*;
// *TODO: Detect when piece is going to go out of bounds and restirct parent from moving there
// TODO: When shape touches the rest of the pieces, re-parent to line entity
// TODO: When line is "full" (has 10 children) clear line and add to score // TODO: When line is "full" (has 10 children) clear line and add to score
fn main() { fn main() {
@ -31,6 +30,7 @@ fn main() {
update_position, update_position,
add_piece.run_if(not(any_with_component::<Shape>)), add_piece.run_if(not(any_with_component::<Shape>)),
clear_line.run_if(any_component_changed::<LineBlocks>), clear_line.run_if(any_component_changed::<LineBlocks>),
adjust_block_lines.run_if(any_component_changed::<Line>),
), ),
) )
.add_systems(Update, draw_grid) .add_systems(Update, draw_grid)
@ -58,7 +58,7 @@ struct ShapeBlock {
} }
// The blocks making up this shape // The blocks making up this shape
#[derive(Component, Default)] #[derive(Component, Default, Debug)]
#[relationship_target(relationship = LineBlock)] #[relationship_target(relationship = LineBlock)]
struct LineBlocks(Vec<Entity>); struct LineBlocks(Vec<Entity>);
@ -72,8 +72,8 @@ struct LineBlock {
} }
// A line holds up to 10 blocks before being cleared // A line holds up to 10 blocks before being cleared
#[derive(Component, Debug)] #[derive(Component, Debug, Clone, Copy)]
struct Line(u8); struct Line(usize);
// Just marks a block either of a shape or line // Just marks a block either of a shape or line
#[derive(Component, Debug)] #[derive(Component, Debug)]
@ -570,15 +570,53 @@ fn add_piece(mut commands: Commands) {
/// When a line reaches 10 blocks, clear it /// When a line reaches 10 blocks, clear it
fn clear_line( fn clear_line(
lines: Query<(Entity, &LineBlocks), (With<LineBlocks>, Changed<LineBlocks>)>, changed_lines: Query<Entity, Changed<LineBlocks>>,
mut lines: Query<(Entity, &LineBlocks, &mut Line)>,
mut commands: Commands, mut commands: Commands,
) { ) {
lines.iter().for_each(|(e, lb)| { let cleared_lines: Vec<usize> = changed_lines
if lb.0.len() == 10 { .iter()
commands.entity(e).despawn_related::<LineBlocks>(); .filter_map(|e| lines.get(e).ok())
// TODO: re-parent all blocks above this to the next line down .filter_map(|(e, lb, Line(i))| {
// TODO: Parent blocks to lines for movement if lb.0.len() == 10 {
} commands.entity(e).despawn_related::<LineBlocks>();
Some(*i)
} else {
None
}
})
.collect();
info!("Cleared lines: {:?}", cleared_lines);
for (idx, cleared_line_number) in cleared_lines.into_iter().sorted().enumerate() {
info!("Processing line {cleared_line_number} ({idx})");
let cleared_line_number = cleared_line_number - idx;
lines.iter_mut().for_each(|(_, _, mut l)| {
let dest = if l.0 > cleared_line_number {
l.0 - 1
} else if l.0 == cleared_line_number {
(Y_MAX - (idx + 1) as u32) as usize
} else {
l.0
};
info!("Moving line {:?} to {:?}", l, dest);
l.0 = dest;
});
}
}
fn adjust_block_lines(
query: Query<(Entity, &Line), Changed<Line>>,
parent: Query<&LineBlocks>,
mut blocks: Query<&mut GridPosition>,
) {
query.iter().for_each(|(e, Line(i))| {
parent.iter_descendants(e).for_each(|block| {
if let Ok(mut gp) = blocks.get_mut(block) {
gp.y = *i as u32;
}
});
}); });
} }
@ -670,8 +708,13 @@ fn deactive_shape(
) { ) {
parent.iter_descendants(trigger.target()).for_each(|block| { parent.iter_descendants(trigger.target()).for_each(|block| {
let GridPosition { y, .. } = grid_positions.get(block).unwrap(); let GridPosition { y, .. } = grid_positions.get(block).unwrap();
let parent_line = lines.iter().find_map(|(e, Line(i))| (*y == *i as u32).then_some(e)).unwrap(); let parent_line = lines
commands.entity(parent_line).add_one_related::<LineBlock>(block); .iter()
.find_map(|(e, Line(i))| (*y == *i as u32).then_some(e))
.unwrap();
commands
.entity(parent_line)
.add_one_related::<LineBlock>(block);
}); });
commands.entity(trigger.target()).despawn(); commands.entity(trigger.target()).despawn();
} }

Loading…
Cancel
Save