use crate::*;
use std::collections::HashMap;
use std::{vec, vec::Vec};
pub(crate) struct TilesetBuilder {
pub specs: Specs,
pub palette_id: u8,
pub(crate) pixels :Vec<u8>,
pub(crate) next_tile:u8,
pub(crate) tile_count:u8,
pub(crate) tile_hash: HashMap::<Vec<u8>, Tile>,
pub(crate) anims: Vec<Anim>,
pub(crate) fonts: Vec<Font>,
pub(crate) tilemaps: Vec<Tilemap>,
pub(crate) anim_names: Vec<String>,
pub(crate) font_names: Vec<String>,
pub(crate) tilemap_names: Vec<String>,
}
impl TilesetBuilder {
pub(crate) fn new(specs:Specs, palette_id:impl PaletteEnum) -> Self {
Self {
specs,
tile_hash: HashMap::new(),
pixels: vec![],
palette_id: palette_id.into(),
next_tile: 0,
tile_count: 0,
anims: vec![],
anim_names: vec![],
fonts: vec![],
font_names: vec![],
tilemaps: vec![],
tilemap_names: vec![],
}
}
pub(crate) fn add_tiles(&mut self, img:&ImageBuilder, group:u8, is_collider:bool) -> Vec<Tile> {
let mut tiles = vec![];
let tile_length = self.specs.tile_width as usize * self.specs.tile_height as usize;
for frame_v in 0 .. img.frames_v as usize {
for frame_h in 0 .. img.frames_h as usize {
for row in 0 .. img.rows_per_frame as usize {
for col in 0 .. img.cols_per_frame as usize {
let mut tile_candidate = vec![0u8; tile_length];
let mut tile_candidate_flip_h = vec![0u8; tile_length];
let abs_col = (frame_h * img.cols_per_frame as usize) + col;
let abs_row = (frame_v * img.rows_per_frame as usize) + row;
for y in 0 .. self.specs.tile_height as usize {
for x in 0 .. self.specs.tile_width as usize {
let mirror_x = self.specs.tile_width as usize - x - 1;
let abs_x = (self.specs.tile_width as usize * abs_col) + x;
let abs_y = (self.specs.tile_height as usize * abs_row) + y;
let index = (img.width * abs_y) + abs_x;
let value = img.pixels[index];
tile_candidate[(self.specs.tile_width as usize * y) + x] = value;
tile_candidate_flip_h[(self.specs.tile_width as usize * y ) + mirror_x] = value;
}
}
if !self.tile_hash.contains_key(&tile_candidate) {
let mut new_tile = Tile{
index: self.next_tile,
group,
flags: 0,
};
new_tile.set_collider(is_collider);
self.tile_hash.insert(tile_candidate.clone(), new_tile);
let mut tile_flipped_h = new_tile;
tile_flipped_h.set_flipped_h(true);
self.tile_hash.insert(tile_candidate_flip_h, tile_flipped_h);
self.pixels.extend_from_slice(&tile_candidate);
println!("Creating tile {}", self.next_tile);
tiles.push(new_tile);
if self.next_tile == 255 { panic!("Error: Tileset capacity exceeded") };
self.next_tile += 1;
self.tile_count += 1;
} else {
let reused_tile = self.tile_hash.get(&tile_candidate).unwrap();
tiles.push(*reused_tile);
}
}
}
}
}
tiles
}
}