104 lines
2.8 KiB
Rust
104 lines
2.8 KiB
Rust
use bevy::prelude::*;
|
|
|
|
use crate::animation::transform::AnimatedTransform;
|
|
|
|
pub struct GridPlugin;
|
|
|
|
impl Plugin for GridPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.add_systems(Startup, setup_grid)
|
|
.add_systems(Update, snap_grid_elements);
|
|
}
|
|
}
|
|
|
|
#[derive(Component)]
|
|
pub struct Grid {
|
|
bounds: Rect,
|
|
columns: usize,
|
|
rows: usize,
|
|
elements: Vec<Option<Entity>>,
|
|
}
|
|
|
|
impl Grid {
|
|
pub fn square(start: Vec2, side: f32, cells: usize) -> Self {
|
|
let mut elements: Vec<Option<Entity>> = Vec::new();
|
|
elements.resize(cells * cells, None);
|
|
Grid {
|
|
bounds: Rect {
|
|
min: start,
|
|
max: start + Vec2::new(side * (cells as f32), side * (cells as f32)),
|
|
},
|
|
columns: cells,
|
|
rows: cells,
|
|
elements: elements,
|
|
}
|
|
}
|
|
|
|
pub fn get_position(&self, index: usize) -> Vec3 {
|
|
let x = index % self.columns;
|
|
let y = (index / self.columns).clamp(0, self.rows - 1);
|
|
|
|
(self.bounds.min + self.cell_size() / 2. + vec2(x as f32, y as f32) * self.cell_size())
|
|
.extend(0.)
|
|
}
|
|
|
|
pub fn is_in_grid(&self, position: Vec2) -> bool {
|
|
self.bounds.contains(position)
|
|
}
|
|
|
|
pub fn is_occupied(&self, position: Vec2) -> bool {
|
|
if self.is_in_grid(position) == false {
|
|
return true;
|
|
}
|
|
|
|
match self.elements[self.indexify_position(position)] {
|
|
Some(_) => true,
|
|
None => false,
|
|
}
|
|
}
|
|
|
|
pub fn is_free(&self, position: Vec2) -> bool {
|
|
self.is_occupied(position) == false
|
|
}
|
|
|
|
pub fn try_set(&mut self, position: Vec2, entity: Entity) -> bool {
|
|
if self.is_occupied(position) {
|
|
return false;
|
|
}
|
|
let index = self.indexify_position(position);
|
|
|
|
self.elements[index] = Some(entity);
|
|
true
|
|
}
|
|
|
|
fn cell_size(&self) -> Vec2 {
|
|
self.bounds.size() / vec2(self.columns as f32, -(self.rows as f32))
|
|
}
|
|
|
|
fn indexify_position(&self, position: Vec2) -> usize {
|
|
let indexified_position = (position / self.cell_size()).floor();
|
|
indexified_position.x as usize + indexified_position.y as usize * self.columns
|
|
}
|
|
}
|
|
|
|
fn setup_grid(mut commands: Commands) {
|
|
commands.spawn(Grid::square(vec2(-244., 192.), 80., 5));
|
|
}
|
|
|
|
fn snap_grid_elements(
|
|
mut transform_query: Query<&mut AnimatedTransform>,
|
|
grid_query: Query<&Grid>,
|
|
) {
|
|
for grid in grid_query {
|
|
for (index, el) in grid.elements.iter().enumerate() {
|
|
let Some(entity) = el else {
|
|
continue;
|
|
};
|
|
let Ok(mut transform) = transform_query.get_mut(entity.clone()) else {
|
|
continue;
|
|
};
|
|
|
|
transform.translation = grid.get_position(index);
|
|
}
|
|
}
|
|
}
|