use crate::core::shader::object::TextureCoordinate;
use crate::core::resource::image::Image;
use crate::core::file;
#[derive(Clone)]
pub struct TileData {
pub name: String,
x1: f32,
y1: f32,
x2: f32,
y2: f32,
}
#[derive(Clone)]
pub enum TileDataRotation {
Bottom,
Left,
Top,
Right,
}
impl TileData {
pub fn texcoord(&self, tile_data_rotation: &TileDataRotation) -> TextureCoordinate {
match tile_data_rotation {
TileDataRotation::Bottom => {
[
self.x1, self.y2,
self.x1, self.y1,
self.x2, self.y1,
self.x2, self.y2,
]
},
TileDataRotation::Left => {
[
self.x2, self.y2,
self.x1, self.y2,
self.x1, self.y1,
self.x2, self.y1,
]
},
TileDataRotation::Top => {
[
self.x2, self.y1,
self.x2, self.y2,
self.x1, self.y2,
self.x1, self.y1,
]
},
TileDataRotation::Right => {
[
self.x1, self.y1,
self.x2, self.y1,
self.x2, self.y2,
self.x1, self.y2,
]
}
}
}
}
pub struct TileMap {
tiles: Vec<TileData>,
image: Image,
pub dim: usize,
}
impl TileMap {
pub fn new(path: &str, image: Image, dim: usize) -> Result<Self, String> {
let file = file::read(path)?;
let image_dim = (image.width, image.height);
let mut tiles = vec![];
for line in file.lines() {
match Self::parse_line(&line) {
Ok((name, x, y)) => {
let x = x as f32;
let y = y as f32;
let dim = dim as f32;
let width = image_dim.0;
let height = image_dim.1;
let x1 = x / width;
let y1 = 1.0 - (y / height);
let x2 = (x + dim) / width;
let y2 = 1.0 - ((y + dim) / height);
let tile_data = TileData {
name, x1, y1, x2, y2
};
tiles.push(tile_data);
},
Err(_) => return Err(format!("Could not parse line '{}'", line)),
}
}
let tilemap = TileMap{tiles, image, dim};
Ok(tilemap)
}
pub fn image(&self) -> Image {
self.image.clone()
}
pub fn as_vec(&self) -> Vec<TileData> {
self.tiles.clone()
}
pub fn get(&self, name: &str) -> Result<TileData, String> {
for item in &self.tiles {
if item.name == name {
return Ok(item.clone());
}
}
Err(format!("Could not get item '{}'.", name))
}
fn parse_line(line: &str) -> Result<(String, usize, usize), std::num::ParseIntError> {
let parts: Vec<&str> = line.split(',').collect();
let name = parts[0].to_string();
let x = parts[1].parse::<usize>()?;
let y = parts[2].parse::<usize>()?;
Ok((name, x, y))
}
}