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>, } impl Grid { pub fn square(start: Vec2, side: f32, cells: usize) -> Self { let mut elements: Vec> = 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); } } }