use crate::prelude::*;
#[derive(Clone, Debug, TypeUlid)]
#[ulid = "01GNF7SRDRN4K8HPW32JAHKMX1"]
pub struct TileLayer {
pub tiles: Vec<Option<Entity>>,
pub grid_size: UVec2,
pub tile_size: Vec2,
pub atlas: Handle<Atlas>,
}
#[derive(Clone, Debug, TypeUlid, Default)]
#[ulid = "01GNZHDZV61TFPEE4GDJY4SRAM"]
pub struct Tile {
pub idx: usize,
pub flip_x: bool,
pub flip_y: bool,
}
impl TileLayer {
pub fn new(grid_size: UVec2, tile_size: Vec2, atlas: Handle<Atlas>) -> Self {
let tile_count = (grid_size.x * grid_size.y) as usize;
let mut tiles = Vec::with_capacity(tile_count);
for _ in 0..tile_count {
tiles.push(None);
}
Self {
tiles,
grid_size,
tile_size,
atlas,
}
}
#[inline]
fn idx(&self, pos: UVec2) -> Option<usize> {
let idx = self.grid_size.x as i32 * pos.y as i32 + pos.x as i32;
idx.try_into().ok()
}
pub fn get(&self, pos: UVec2) -> Option<Entity> {
self.idx(pos)
.and_then(|idx| self.tiles.get(idx).cloned().flatten())
}
pub fn set(&mut self, pos: UVec2, entity: Option<Entity>) {
let idx = self.idx(pos).expect("Tile pos out of bounds");
*self.tiles.get_mut(idx).unwrap_or_else(|| {
panic!(
"Tile pos out of range of tile size: pos {:?} size {:?}",
pos, self.grid_size
)
}) = entity;
}
}