bones_framework/render/
tilemap.rs1use crate::prelude::*;
4
5#[derive(Clone, Debug, HasSchema, Default)]
7pub struct TileLayer {
8 pub tiles: Vec<Option<Entity>>,
10 pub grid_size: UVec2,
12 pub tile_size: Vec2,
14 pub atlas: Handle<Atlas>,
16}
17
18#[derive(Clone, Debug, HasSchema, Default)]
20#[repr(C)]
21pub struct Tile {
22 pub idx: u32,
24 pub flip_x: bool,
26 pub flip_y: bool,
28}
29
30impl TileLayer {
31 pub fn new(grid_size: UVec2, tile_size: Vec2, atlas: Handle<Atlas>) -> Self {
33 let mut out = Self {
34 tiles: Vec::new(),
35 grid_size,
36 tile_size,
37 atlas,
38 };
39 out.ensure_space();
40 out
41 }
42
43 fn ensure_space(&mut self) {
45 let tile_count = (self.grid_size.x * self.grid_size.y) as usize;
46
47 if unlikely(self.tiles.len() < tile_count) {
48 self.tiles
49 .extend((0..(tile_count - self.tiles.len())).map(|_| None));
50 }
51 }
52
53 #[inline]
55 pub fn idx(&self, pos: UVec2) -> u32 {
56 self.grid_size.x * pos.y + pos.x
57 }
58
59 pub fn pos(&self, idx: u32) -> UVec2 {
61 let y = idx / self.grid_size.x;
62 let x = idx - (y * self.grid_size.x);
63
64 UVec2::new(x, y)
65 }
66
67 pub fn get(&self, pos: UVec2) -> Option<Entity> {
70 let idx = self.idx(pos);
71 self.tiles.get(idx as usize).cloned().flatten()
72 }
73
74 pub fn set(&mut self, pos: UVec2, entity: Option<Entity>) {
76 self.ensure_space();
77
78 let idx = self.idx(pos);
79 *self.tiles.get_mut(idx as usize).unwrap_or_else(|| {
80 panic!(
81 "Tile pos out of range of tile size: pos {:?} size {:?}",
82 pos, self.grid_size
83 )
84 }) = entity;
85 }
86}