From 7e9bad32861a947d70844e79e411b43bbd9d2696 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Mon, 1 Aug 2022 11:43:14 +0200 Subject: [PATCH] Fix view --- src/engine/bbox.rs | 8 ++++++++ src/engine/character.rs | 2 +- src/engine/mod.rs | 13 ++++++++---- src/engine/scene.rs | 45 +++++++++++++++++++++-------------------- src/engine/vector.rs | 19 ++++++++++++++++- 5 files changed, 59 insertions(+), 28 deletions(-) diff --git a/src/engine/bbox.rs b/src/engine/bbox.rs index 420a6a7..6230de7 100644 --- a/src/engine/bbox.rs +++ b/src/engine/bbox.rs @@ -20,4 +20,12 @@ impl Bbox { size: Vector::new(w, h), } } + + /// Creates a new bounding box from its center and size. + pub fn from_center_and_size(center: Vector, size: Vector) -> Bbox { + Bbox { + position: center - size / 2.0, + size, + } + } } diff --git a/src/engine/character.rs b/src/engine/character.rs index 24da52c..149db05 100644 --- a/src/engine/character.rs +++ b/src/engine/character.rs @@ -137,7 +137,7 @@ impl Character { /// Returns a view that looks at the character. pub fn view(&self) -> Bbox { - Bbox::new(self.position.x, self.position.y, 24.0 * 16.0, 24.0 * 9.0) + Bbox::from_center_and_size(self.position, Vector::new(24.0 * 16.0, 24.0 * 9.0)) } /// Returns the collision bounding box of the character. diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 93dd638..747e3a1 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -160,13 +160,17 @@ impl Engine { } /// Draw a drawable. - pub fn draw(&self, drawable: &D) -> Result<()> { + pub fn draw(&self, drawable: &D, view: Bbox) -> Result<()> { let inner = self.inner.borrow(); let image = inner.textures.get(drawable.texture()); let source = drawable.texture_rect(inner.after_loop); let mut dest = source.clone(); - dest.position = drawable.position(); + dest.position = drawable.position() - view.position; + dest.position.x *= 1920.0 / view.size.x; + dest.position.y *= 1080.0 / view.size.y; + dest.size.x *= 1920.0 / view.size.x; + dest.size.y *= 1080.0 / view.size.y; image.render(source, dest, &self.context)?; Ok(()) @@ -175,6 +179,7 @@ impl Engine { /// Performs the rendering of the engine. pub fn render(&self) -> Result<()> { let inner = self.inner.borrow(); + let view = inner.scene.view().unwrap(); // TODO remove this unwrap // Clear render self.context.clear_rect(0.0, 0.0, 1920.0, 1080.0); @@ -191,7 +196,7 @@ impl Engine { for j in 0..cols { let tile = map.at(i, j); if tile.graphic.is_visible() { - self.draw(&tile)?; + self.draw(&tile, view)?; } } } @@ -199,7 +204,7 @@ impl Engine { // Draw characters for c in inner.scene.characters() { if true { - self.draw(c)?; + self.draw(c, view)?; } } diff --git a/src/engine/scene.rs b/src/engine/scene.rs index 28ebfbd..5b308cc 100644 --- a/src/engine/scene.rs +++ b/src/engine/scene.rs @@ -2,6 +2,7 @@ use std::time::{Duration, SystemTime}; +use crate::engine::bbox::Bbox; use crate::engine::character::Character; use crate::engine::event::{Event, Keyboard}; use crate::engine::map::Map; @@ -54,34 +55,34 @@ impl Scene { None } - // /// Returns the right view. - // pub fn view(&self) -> Option { - // let view = self.controlable()?.view(); - // let mut center = view.center(); - // let size = view.size(); + /// Returns the right view. + pub fn view(&self) -> Option { + let view = self.controlable()?.view(); + let mut center = view.position + view.size / 2.0; + let size = view.size; - // // Clamp center so that the view doesn't show things outside the level. - // if center.x - size.x / 2.0 < 0.0 { - // center.x = size.x / 2.0; - // } + // Clamp center so that the view doesn't show things outside the level. + if center.x - size.x / 2.0 < 0.0 { + center.x = size.x / 2.0; + } - // if center.y - size.y / 2.0 < 0.0 { - // center.y = size.y / 2.0; - // } + if center.y - size.y / 2.0 < 0.0 { + center.y = size.y / 2.0; + } - // let right_limit = self.map.cols() as f32 * SPRITE_SIZE_F32; - // let bottom_limit = self.map.rows() as f32 * SPRITE_SIZE_F32; + let right_limit = self.map.cols() as f64 * SPRITE_SIZE; + let bottom_limit = self.map.rows() as f64 * SPRITE_SIZE; - // if center.x + size.x / 2.0 > right_limit { - // center.x = right_limit - size.x / 2.0; - // } + if center.x + size.x / 2.0 > right_limit { + center.x = right_limit - size.x / 2.0; + } - // if center.y + size.y / 2.0 > bottom_limit { - // center.y = bottom_limit - size.y / 2.0; - // } + if center.y + size.y / 2.0 > bottom_limit { + center.y = bottom_limit - size.y / 2.0; + } - // Some(View::new(center, size)) - // } + Some(Bbox::from_center_and_size(center, size)) + } /// Updates the whole scene. pub fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard) -> State { diff --git a/src/engine/vector.rs b/src/engine/vector.rs index dba62eb..66bbd86 100644 --- a/src/engine/vector.rs +++ b/src/engine/vector.rs @@ -1,7 +1,7 @@ //! A module for basic maths. use std::fmt; -use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; /// A 2 dimensional vector. #[derive(Copy, Clone)] @@ -81,6 +81,23 @@ impl Mul for f64 { } } +impl Div for Vector { + type Output = Vector; + fn div(self, rhs: f64) -> Vector { + Vector { + x: self.x / rhs, + y: self.y / rhs, + } + } +} + +impl DivAssign for Vector { + fn div_assign(&mut self, rhs: f64) { + self.x /= rhs; + self.y /= rhs; + } +} + impl fmt::Display for Vector { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "({}, {})", self.x, self.y)