card-game/src/grid.rs
2026-01-27 05:56:42 +05:00

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);
}
}
}