|
|
|
|
@ -24,6 +24,7 @@ fn main() {
|
|
|
|
|
})
|
|
|
|
|
.init_state::<GameState>()
|
|
|
|
|
.init_resource::<ShapesBuffer>()
|
|
|
|
|
.init_resource::<ShapeStore>()
|
|
|
|
|
.init_resource::<Score>()
|
|
|
|
|
.add_systems(Startup, (init_world, init_debug_ui, init_ui))
|
|
|
|
|
// Input and basic systems
|
|
|
|
|
@ -49,7 +50,6 @@ fn main() {
|
|
|
|
|
update_shape_blocks
|
|
|
|
|
.run_if(any_component_added::<Shape>.or(any_component_changed::<Shape>)).after(update_position),
|
|
|
|
|
deactivate_shape.run_if(any_component_removed::<Shape>).after(update_shape_blocks),
|
|
|
|
|
check_line_removal,
|
|
|
|
|
// Clearing lines systems
|
|
|
|
|
clear_line.run_if(any_component_changed::<LineBlocks>),
|
|
|
|
|
adjust_block_lines
|
|
|
|
|
@ -62,6 +62,7 @@ fn main() {
|
|
|
|
|
Update,
|
|
|
|
|
(
|
|
|
|
|
sync_resource_to_ui::<ShapesBuffer>.run_if(resource_changed::<ShapesBuffer>),
|
|
|
|
|
sync_resource_to_ui::<ShapeStore>.run_if(resource_changed::<ShapeStore>),
|
|
|
|
|
sync_resource_to_ui::<Score>.run_if(resource_changed::<Score>),
|
|
|
|
|
sync_singleton_to_ui::<Shape>.run_if(any_component_changed::<Shape>),
|
|
|
|
|
),
|
|
|
|
|
@ -238,6 +239,18 @@ impl Display for ShapesBuffer {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Resource, Debug, Default)]
|
|
|
|
|
struct ShapeStore(Option<Shape>);
|
|
|
|
|
|
|
|
|
|
impl Display for ShapeStore {
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
match self.0 {
|
|
|
|
|
Some(inner) => write!(f, "{}", inner.as_ascii()),
|
|
|
|
|
None => write!(f, "---")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_world(
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
|
|
|
@ -279,6 +292,16 @@ fn init_ui(mut commands: Commands) {
|
|
|
|
|
parent.spawn(Text::new("Next:"));
|
|
|
|
|
parent.spawn((Text::new("???"), SyncResource::<ShapesBuffer>::default()));
|
|
|
|
|
});
|
|
|
|
|
parent
|
|
|
|
|
.spawn((Node {
|
|
|
|
|
flex_direction: FlexDirection::Column,
|
|
|
|
|
align_items: AlignItems::Center,
|
|
|
|
|
..default()
|
|
|
|
|
},))
|
|
|
|
|
.with_children(|parent| {
|
|
|
|
|
parent.spawn(Text::new("Swap:"));
|
|
|
|
|
parent.spawn((Text::new("???"), SyncResource::<ShapeStore>::default()));
|
|
|
|
|
});
|
|
|
|
|
parent
|
|
|
|
|
.spawn((Node {
|
|
|
|
|
flex_direction: FlexDirection::Column,
|
|
|
|
|
@ -589,9 +612,12 @@ fn kb_input(
|
|
|
|
|
KeyCode::ArrowRight => {
|
|
|
|
|
commands.entity(e).trigger(Movement::Right);
|
|
|
|
|
}
|
|
|
|
|
KeyCode::Space => {
|
|
|
|
|
KeyCode::Enter => {
|
|
|
|
|
commands.entity(e).trigger(Movement::Skip);
|
|
|
|
|
}
|
|
|
|
|
KeyCode::Space => {
|
|
|
|
|
commands.entity(e).trigger(Swap);
|
|
|
|
|
}
|
|
|
|
|
KeyCode::Escape => next.set(match curr.get() {
|
|
|
|
|
GameState::Falling => GameState::Pause,
|
|
|
|
|
GameState::Pause => GameState::Falling,
|
|
|
|
|
@ -650,7 +676,8 @@ fn add_piece(mut commands: Commands, mut shapes: ResMut<ShapesBuffer>) {
|
|
|
|
|
GridPosition { y: Y_MAX - this_shape.height(), ..default() },
|
|
|
|
|
this_shape,
|
|
|
|
|
))
|
|
|
|
|
.observe(movement);
|
|
|
|
|
.observe(movement)
|
|
|
|
|
.observe(swap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// When a line reaches 10 blocks, clear it
|
|
|
|
|
@ -727,6 +754,11 @@ fn adjust_block_lines(
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Swap the current piece out
|
|
|
|
|
#[derive(Event, Copy, Clone, PartialEq)]
|
|
|
|
|
struct Swap;
|
|
|
|
|
|
|
|
|
|
/// Movement events triggered on the piece
|
|
|
|
|
#[derive(Event, Copy, Clone, PartialEq)]
|
|
|
|
|
enum Movement {
|
|
|
|
|
Down,
|
|
|
|
|
@ -816,15 +848,29 @@ fn movement(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn check_line_removal(
|
|
|
|
|
mut events: RemovedComponents<Line>,
|
|
|
|
|
fn swap(
|
|
|
|
|
trigger: Trigger<Swap>,
|
|
|
|
|
mut shapes: Query<&mut Shape>,
|
|
|
|
|
mut store: ResMut<ShapeStore>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
events.read().for_each(|e| {
|
|
|
|
|
info!("Line entity {:?} removed", e);
|
|
|
|
|
});
|
|
|
|
|
info!("Swap called");
|
|
|
|
|
match store.0.as_mut() {
|
|
|
|
|
None => {
|
|
|
|
|
// Copy current shape into store
|
|
|
|
|
// De-activate entity
|
|
|
|
|
store.0 = Some(*shapes.get(trigger.target()).unwrap());
|
|
|
|
|
commands.entity(trigger.target()).despawn_related::<ShapeBlocks>().despawn();
|
|
|
|
|
}
|
|
|
|
|
Some(inner) => {
|
|
|
|
|
// Copy current shape into store
|
|
|
|
|
// Copy old shape into entity
|
|
|
|
|
let mut curr = shapes.get_mut(trigger.target()).unwrap();
|
|
|
|
|
std::mem::swap(&mut (*inner), &mut (*curr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Just despawn?
|
|
|
|
|
fn deactivate_shape(
|
|
|
|
|
mut events: RemovedComponents<Shape>,
|
|
|
|
|
grid_positions: Query<&GridPosition>,
|
|
|
|
|
|