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 = []
[dependencies]
itertools = "*"
thiserror = "2.0.12"
[dependencies.serde]

@ -1,10 +1,9 @@
// Bevy basically forces "complex types" with Querys
#![allow(clippy::type_complexity)]
use itertools::Itertools;
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
fn main() {
@ -31,6 +30,7 @@ fn main() {
update_position,
add_piece.run_if(not(any_with_component::<Shape>)),
clear_line.run_if(any_component_changed::<LineBlocks>),
adjust_block_lines.run_if(any_component_changed::<Line>),
),
)
.add_systems(Update, draw_grid)
@ -58,7 +58,7 @@ struct ShapeBlock {
}
// The blocks making up this shape
#[derive(Component, Default)]
#[derive(Component, Default, Debug)]
#[relationship_target(relationship = LineBlock)]
struct LineBlocks(Vec<Entity>);
@ -72,8 +72,8 @@ struct LineBlock {
}
// A line holds up to 10 blocks before being cleared
#[derive(Component, Debug)]
struct Line(u8);
#[derive(Component, Debug, Clone, Copy)]
struct Line(usize);
// Just marks a block either of a shape or line
#[derive(Component, Debug)]
@ -570,15 +570,53 @@ fn add_piece(mut commands: Commands) {
/// When a line reaches 10 blocks, clear it
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,
) {
lines.iter().for_each(|(e, lb)| {
let cleared_lines: Vec<usize> = changed_lines
.iter()
.filter_map(|e| lines.get(e).ok())
.filter_map(|(e, lb, Line(i))| {
if lb.0.len() == 10 {
commands.entity(e).despawn_related::<LineBlocks>();
// TODO: re-parent all blocks above this to the next line down
// TODO: Parent blocks to lines for movement
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| {
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();
commands.entity(parent_line).add_one_related::<LineBlock>(block);
let parent_line = lines
.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();
}

Loading…
Cancel
Save