use ggez::graphics::{spritebatch::SpriteBatch, DrawParam, Rect}; use glam; use std::f32::consts::PI; use xml::reader::XmlEvent; use crate::constants; use crate::xmlelements::XMLElements; #[derive(Clone, Debug, PartialEq)] pub struct Tile { pub source: Rect, pub properties: Properties, } impl Tile { pub fn new(source: Rect, properties: Properties) -> Tile { Tile { source, properties } } pub fn draw(&self, spritebatch: &mut SpriteBatch, position: glam::Vec2) { let draw = match self.properties.visible { Some(draw) => draw, None => true, }; if draw { spritebatch.add( DrawParam::default() .src(self.source) .rotation(self.properties.rotation) .offset(glam::Vec2::new(0.5, 0.5)) .dest(position) .scale(glam::Vec2::new( constants::TILE_SCALE, constants::TILE_SCALE, )), ); } } } impl Default for Tile { fn default() -> Tile { Tile::new(Rect::zero(), Properties::default()) } } #[derive(Debug, Clone, PartialEq)] pub struct Properties { pub entity: Option, pub rotation: f32, pub keyframe: Option, pub delay: Option, pub scramble_delay: Option, pub spawn: Option, pub visible: Option, } impl Properties { pub fn new(properties_elements: Vec) -> Properties { let entity = match XMLElements::get_attribute_value(&properties_elements, "entity") { Ok(entity) => entity.parse().ok(), Err(_) => None, }; let keyframe = match XMLElements::get_attribute_value(&properties_elements, "keyframe") { Ok(keyframe) => keyframe.parse().ok(), Err(_) => None, }; let spawn = XMLElements::get_attribute_value(&properties_elements, "spawn").ok(); let visible = match XMLElements::get_attribute_value(&properties_elements, "visible") { Ok(visible) => visible.parse().ok(), Err(_) => None, }; let delay = match XMLElements::get_attribute_value(&properties_elements, "delay") { Ok(delay) => delay.parse().ok(), Err(_) => None, }; let scramble_delay = match XMLElements::get_attribute_value(&properties_elements, "scramble_delay") { Ok(scramble_delay) => scramble_delay.parse().ok(), Err(_) => None, }; Properties { rotation: 0.0, entity, keyframe, delay, scramble_delay, spawn, visible, } } } impl Default for Properties { fn default() -> Properties { Properties { rotation: 0.0, entity: None, keyframe: None, delay: None, scramble_delay: None, spawn: None, visible: None, } } } pub fn convert_angle_to_rad(angle: f32) -> f32 { angle * (PI / 180.0) } pub fn flip(tile: Tile) -> Tile { let mut t = tile; t.source.x *= -1.0; t.source.x -= t.source.w; t } pub fn rotate(tile: Tile, angle: f32) -> Tile { let mut t = tile; t.properties.rotation = convert_angle_to_rad(angle); t }