use nalgebra_glm::Vec2;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct TileData {
pub tile_id: u32,
pub flip_x: bool,
pub flip_y: bool,
}
impl TileData {
pub fn new(tile_id: u32) -> Self {
Self {
tile_id,
flip_x: false,
flip_y: false,
}
}
pub fn with_flip_x(mut self, flip_x: bool) -> Self {
self.flip_x = flip_x;
self
}
pub fn with_flip_y(mut self, flip_y: bool) -> Self {
self.flip_y = flip_y;
self
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Tilemap {
pub position: Vec2,
pub tile_size: Vec2,
pub grid_width: u32,
pub grid_height: u32,
pub tiles: Vec<Option<TileData>>,
pub texture_index: u32,
pub sheet_columns: u32,
pub sheet_rows: u32,
pub depth: f32,
pub color: [f32; 4],
pub uv_max: Vec2,
}
impl Default for Tilemap {
fn default() -> Self {
Self {
position: Vec2::new(0.0, 0.0),
tile_size: Vec2::new(16.0, 16.0),
grid_width: 0,
grid_height: 0,
tiles: Vec::new(),
texture_index: 0,
sheet_columns: 1,
sheet_rows: 1,
depth: 0.0,
color: [1.0, 1.0, 1.0, 1.0],
uv_max: Vec2::new(1.0, 1.0),
}
}
}
impl Tilemap {
pub fn new(position: Vec2, tile_size: Vec2, grid_width: u32, grid_height: u32) -> Self {
let tile_count = (grid_width * grid_height) as usize;
Self {
position,
tile_size,
grid_width,
grid_height,
tiles: vec![None; tile_count],
..Default::default()
}
}
pub fn with_texture(mut self, texture_index: u32) -> Self {
self.texture_index = texture_index;
self
}
pub fn with_sheet_layout(mut self, columns: u32, rows: u32) -> Self {
self.sheet_columns = columns;
self.sheet_rows = rows;
self
}
pub fn with_depth(mut self, depth: f32) -> Self {
self.depth = depth;
self
}
pub fn with_color(mut self, color: [f32; 4]) -> Self {
self.color = color;
self
}
pub fn with_uv_max(mut self, uv_max: Vec2) -> Self {
self.uv_max = uv_max;
self
}
pub fn set_tile(&mut self, col: u32, row: u32, tile_data: Option<TileData>) {
if col < self.grid_width && row < self.grid_height {
let index = (row * self.grid_width + col) as usize;
self.tiles[index] = tile_data;
}
}
pub fn get_tile(&self, col: u32, row: u32) -> Option<&TileData> {
if col < self.grid_width && row < self.grid_height {
let index = (row * self.grid_width + col) as usize;
self.tiles[index].as_ref()
} else {
None
}
}
pub fn fill(&mut self, tile_data: TileData) {
for tile in &mut self.tiles {
*tile = Some(tile_data.clone());
}
}
}