|
|
|
@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
#![allow(clippy::type_complexity)]
|
|
|
|
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO:
|
|
|
|
// TODO:
|
|
|
|
@ -33,15 +35,24 @@ impl Plugin for BlocksPlugin {
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
app.init_asset::<ShapeAsset>()
|
|
|
|
app.init_asset::<ShapeAsset>()
|
|
|
|
.init_asset_loader::<ShapeAssetLoader>()
|
|
|
|
.init_asset_loader::<ShapeAssetLoader>()
|
|
|
|
|
|
|
|
.add_message::<Movement>()
|
|
|
|
.add_systems(OnEnter(Loading(true)), load_assets.run_if(run_once))
|
|
|
|
.add_systems(OnEnter(Loading(true)), load_assets.run_if(run_once))
|
|
|
|
.add_systems(OnEnter(GameState::Setup), (setup_camera, setup_blocks))
|
|
|
|
.add_systems(OnEnter(GameState::Setup), (setup_camera, setup_blocks))
|
|
|
|
.add_systems(
|
|
|
|
.add_systems(
|
|
|
|
Update,
|
|
|
|
Update,
|
|
|
|
updated_shape_asset.run_if(on_message::<AssetEvent<ShapeAsset>>),
|
|
|
|
(
|
|
|
|
|
|
|
|
updated_shape_asset.run_if(on_message::<AssetEvent<ShapeAsset>>),
|
|
|
|
|
|
|
|
update_grid_position.run_if(
|
|
|
|
|
|
|
|
any_component_added::<GridPosition>
|
|
|
|
|
|
|
|
.or(any_component_changed::<GridPosition>),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
propogate_grid_position.run_if(any_component_changed::<GridPosition>),
|
|
|
|
|
|
|
|
handle_kb_input.run_if(on_message::<KeyboardInput>),
|
|
|
|
|
|
|
|
handle_movement.run_if(on_message::<Movement>),
|
|
|
|
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.add_observer(add_shape)
|
|
|
|
.add_observer(add_shape)
|
|
|
|
.add_observer(add_relative_position)
|
|
|
|
.add_observer(add_relative_position);
|
|
|
|
.add_observer(add_grid_position);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -78,13 +89,13 @@ impl ShapeAsset {
|
|
|
|
(self.mesh.clone(), self.material.clone(), b),
|
|
|
|
(self.mesh.clone(), self.material.clone(), b),
|
|
|
|
(self.mesh.clone(), self.material.clone(), c),
|
|
|
|
(self.mesh.clone(), self.material.clone(), c),
|
|
|
|
(self.mesh.clone(), self.material.clone(), d),
|
|
|
|
(self.mesh.clone(), self.material.clone(), d),
|
|
|
|
])
|
|
|
|
]),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// The main play area grid coordinates
|
|
|
|
/// The main play area grid coordinates
|
|
|
|
#[derive(Component)]
|
|
|
|
#[derive(Component, Debug, Clone)]
|
|
|
|
#[require(Transform)]
|
|
|
|
#[require(Transform)]
|
|
|
|
struct GridPosition {
|
|
|
|
struct GridPosition {
|
|
|
|
pub x: usize,
|
|
|
|
pub x: usize,
|
|
|
|
@ -108,6 +119,31 @@ impl Into<Vec3> for &GridPosition {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl std::ops::AddAssign<RelativePosition> for GridPosition {
|
|
|
|
|
|
|
|
fn add_assign(&mut self, rhs: RelativePosition) {
|
|
|
|
|
|
|
|
self.x = self.x.strict_add_signed(rhs.x);
|
|
|
|
|
|
|
|
self.y = self.y.strict_add_signed(rhs.y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl std::ops::SubAssign<RelativePosition> for GridPosition {
|
|
|
|
|
|
|
|
fn sub_assign(&mut self, rhs: RelativePosition) {
|
|
|
|
|
|
|
|
self.x = self.x.strict_sub_signed(rhs.x);
|
|
|
|
|
|
|
|
self.y = self.y.strict_sub_signed(rhs.y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl std::ops::Add<RelativePosition> for GridPosition {
|
|
|
|
|
|
|
|
type Output = GridPosition;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn add(self, rhs: RelativePosition) -> GridPosition {
|
|
|
|
|
|
|
|
GridPosition {
|
|
|
|
|
|
|
|
x: self.x.strict_add_signed(rhs.x),
|
|
|
|
|
|
|
|
y: self.y.strict_add_signed(rhs.y),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Block positions relative to the shape's center
|
|
|
|
/// Block positions relative to the shape's center
|
|
|
|
#[derive(Component, PartialEq, Debug, Clone, Copy)]
|
|
|
|
#[derive(Component, PartialEq, Debug, Clone, Copy)]
|
|
|
|
pub(crate) struct RelativePosition {
|
|
|
|
pub(crate) struct RelativePosition {
|
|
|
|
@ -115,9 +151,15 @@ pub(crate) struct RelativePosition {
|
|
|
|
pub y: isize,
|
|
|
|
pub y: isize,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl RelativePosition {
|
|
|
|
|
|
|
|
fn new(x: isize, y: isize) -> Self {
|
|
|
|
|
|
|
|
RelativePosition { x, y }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl From<(isize, isize)> for RelativePosition {
|
|
|
|
impl From<(isize, isize)> for RelativePosition {
|
|
|
|
fn from((x, y): (isize, isize)) -> Self {
|
|
|
|
fn from((x, y): (isize, isize)) -> Self {
|
|
|
|
RelativePosition { x, y }
|
|
|
|
RelativePosition::new(x, y)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -294,13 +336,100 @@ fn add_relative_position(
|
|
|
|
let parent_shape = blocks.get(event.entity).unwrap();
|
|
|
|
let parent_shape = blocks.get(event.entity).unwrap();
|
|
|
|
let rp = relative_positions.get(event.entity).unwrap();
|
|
|
|
let rp = relative_positions.get(event.entity).unwrap();
|
|
|
|
let gp = grid_positions.get(parent_shape.0).unwrap();
|
|
|
|
let gp = grid_positions.get(parent_shape.0).unwrap();
|
|
|
|
commands.entity(event.entity).insert(gp.with_relative_offset(rp));
|
|
|
|
commands
|
|
|
|
|
|
|
|
.entity(event.entity)
|
|
|
|
|
|
|
|
.insert(gp.with_relative_offset(rp));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn add_grid_position(
|
|
|
|
/// Populate Transform when GridPosition is added to an entity
|
|
|
|
event: On<Add, GridPosition>,
|
|
|
|
fn update_grid_position(
|
|
|
|
mut query: Query<(&GridPosition, &mut Transform)>,
|
|
|
|
mut query: Query<
|
|
|
|
|
|
|
|
(&GridPosition, &mut Transform),
|
|
|
|
|
|
|
|
Or<(Added<GridPosition>, Changed<GridPosition>)>,
|
|
|
|
|
|
|
|
>,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
let (gp, mut t) = query.get_mut(event.entity).unwrap();
|
|
|
|
query.iter_mut().for_each(|(gp, mut t)| {
|
|
|
|
t.translation = gp.into();
|
|
|
|
info!("Updating grid position to {:?}", gp);
|
|
|
|
|
|
|
|
t.translation = gp.into();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn propogate_grid_position(
|
|
|
|
|
|
|
|
parent: Query<(&GridPosition, &ShapeBlocks), Changed<GridPosition>>,
|
|
|
|
|
|
|
|
mut children: Query<(&mut GridPosition, &RelativePosition), Without<ShapeBlocks>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
parent.iter().for_each(|(parent_gp, sbs)| {
|
|
|
|
|
|
|
|
sbs.iter().for_each(|e| {
|
|
|
|
|
|
|
|
let (mut gp, rp) = children.get_mut(e).unwrap();
|
|
|
|
|
|
|
|
*gp = parent_gp.clone() + *rp;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Movement message used to propose/plan a move
|
|
|
|
|
|
|
|
#[derive(Debug, Message)]
|
|
|
|
|
|
|
|
enum Movement {
|
|
|
|
|
|
|
|
Rotate,
|
|
|
|
|
|
|
|
Left,
|
|
|
|
|
|
|
|
Down,
|
|
|
|
|
|
|
|
Right,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Handle KeyBoard input
|
|
|
|
|
|
|
|
/// Nothing is handled directly in this method,
|
|
|
|
|
|
|
|
/// All key presses result in either a message, event, or state change
|
|
|
|
|
|
|
|
fn handle_kb_input(mut input: MessageReader<KeyboardInput>, mut moves: MessageWriter<Movement>) {
|
|
|
|
|
|
|
|
input.read().for_each(
|
|
|
|
|
|
|
|
|KeyboardInput {
|
|
|
|
|
|
|
|
key_code, state, ..
|
|
|
|
|
|
|
|
}| {
|
|
|
|
|
|
|
|
if *state == ButtonState::Pressed {
|
|
|
|
|
|
|
|
match key_code {
|
|
|
|
|
|
|
|
KeyCode::ArrowLeft => {
|
|
|
|
|
|
|
|
moves.write(Movement::Left);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyCode::ArrowRight => {
|
|
|
|
|
|
|
|
moves.write(Movement::Right);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyCode::ArrowDown => {
|
|
|
|
|
|
|
|
moves.write(Movement::Down);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyCode::ArrowUp => {
|
|
|
|
|
|
|
|
moves.write(Movement::Rotate);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyCode::Escape => todo!("Pause Toggle"),
|
|
|
|
|
|
|
|
_ => (), // Do nothing
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn handle_movement(
|
|
|
|
|
|
|
|
mut moves: MessageReader<Movement>,
|
|
|
|
|
|
|
|
mut query: Query<&mut GridPosition, With<ShapeBlocks>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
moves.read().for_each(|m| match m {
|
|
|
|
|
|
|
|
Movement::Left => {
|
|
|
|
|
|
|
|
query.iter_mut().for_each(|mut gp| {
|
|
|
|
|
|
|
|
info!("moving shape left");
|
|
|
|
|
|
|
|
*gp -= RelativePosition::new(1, 0);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Movement::Right => {
|
|
|
|
|
|
|
|
query.iter_mut().for_each(|mut gp| {
|
|
|
|
|
|
|
|
info!("moving shape right");
|
|
|
|
|
|
|
|
*gp += RelativePosition::new(1, 0);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Movement::Down => {
|
|
|
|
|
|
|
|
query.iter_mut().for_each(|mut gp| {
|
|
|
|
|
|
|
|
info!("moving shape down");
|
|
|
|
|
|
|
|
*gp -= RelativePosition::new(0, 1);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Movement::Rotate => {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|