use super::Cartesian; use crate::DrawContext; #[derive(Debug, Clone, Copy)] pub struct WorldPosition { pub pos: Cartesian, // True world position pub par: f64, // Parallax factor } impl WorldPosition { pub fn new(pos: Cartesian, par: f64) -> Self { WorldPosition { pos: pos, par } } fn from_screen_position(dc: &DrawContext, pos: Cartesian, par: f64) -> Self { WorldPosition { par, pos: ((pos * Cartesian::new(1.0, -1.0)) + dc.top_left) * par + dc.camera.pos, } } /// Get the position of this drawable on the screen /// (0, 0) is at top-left corner. /// /// Returned position is this object's center. pub fn screen_position(&self, dc: &DrawContext) -> Cartesian { let par = self.par; let pos: Cartesian = self.pos.into(); return (((pos - dc.camera.pos) / par) - dc.top_left) * Cartesian::new(1.0, -1.0); } /// Get the position of this drawable on the screen /// (0, 0) is at top-left corner. /// /// Returned position is this object's center. pub fn screen_position_real(&self, dc: &DrawContext) -> Cartesian { let pos: Cartesian = self.pos.into(); return ((pos - dc.camera.pos) - dc.top_left) * Cartesian::new(1.0, -1.0); } /// Is this object on screen? fn on_screen(&self, dc: &DrawContext) -> bool { let pos = self.screen_position(dc); let (width, height) = (10, 10); //TODO: actual // Don't draw if we're not on the screen. // An offset is included to ensure we're completely // off the screen. We add the whole width intentionally. return !(pos.x < -1.0 * (width as f64) || pos.x > dc.window_size.x + width as f64 || pos.y < -1.0 * (height as f64) || pos.y > dc.window_size.y + height as f64); } } impl Into for WorldPosition { fn into(self) -> Cartesian { self.pos.into() } }