diff options
Diffstat (limited to 'graphics')
| -rw-r--r-- | graphics/src/render.rs | 107 |
1 files changed, 58 insertions, 49 deletions
diff --git a/graphics/src/render.rs b/graphics/src/render.rs index 8c88210..a5cdf09 100644 --- a/graphics/src/render.rs +++ b/graphics/src/render.rs @@ -5,13 +5,15 @@ /// The (prefered) view distance of the game const VIEW_DISTANCE: i32 = 10; -use std::ops::{Div, Sub}; +use std::ops::Div; -use dungeon::{Dungeon, Entity, Floor, MAP_SIZE, Player, Pos, Tile}; +use dungeon::{Dungeon, Entity, Floor, MAP_SIZE, Pos, Tile}; use raylib::{ RaylibThread, + camera::Camera2D, color::Color, - math::{Rectangle, Vector2}, + ffi, + math::Vector2, prelude::{RaylibDraw, RaylibDrawHandle, RaylibHandle, RaylibTextureModeExt}, texture::RenderTexture2D, }; @@ -40,10 +42,22 @@ impl Renderer { thread: &'a RaylibThread, ) -> FrameRenderer<'a> { let draw_handle = handle.begin_drawing(thread); + + // calculate the scaling factor + let width = draw_handle.get_render_width(); + let height = draw_handle.get_render_height(); + let tile_size = { + let size = width.max(height); + let dist = VIEW_DISTANCE * 2 + 1; + // TODO: force by 16 scaling levels + size.div(dist).max(16) + }; + FrameRenderer { handle: draw_handle, thread, renderer: self, + tile_size, } } } @@ -57,6 +71,8 @@ pub struct FrameRenderer<'a> { thread: &'a RaylibThread, /// Mutable reference to the main renderer (stores persistant data) renderer: &'a mut Renderer, + /// The tile size for this frame + tile_size: i32, } impl<'a> FrameRenderer<'a> { /// Returns last computed fps @@ -70,29 +86,22 @@ impl<'a> FrameRenderer<'a> { &self.renderer.image } - /// Returns the current render width - fn render_width(&self) -> i32 { - self.handle.get_render_width() - } - - /// Returns the current render height - fn render_height(&self) -> i32 { - self.handle.get_render_height() - } - - /// Returns the wanted map tile size - fn tile_size(&self) -> i32 { - // the pixl size we will base everything on - let size = self.render_width().max(self.render_height()); - // min visible tiles - let dist = VIEW_DISTANCE * 2 + 1; - // get crude number of pixles - // TODO: force scaling levels - size.div(dist).max(16) + /// Returns a raylib camera for the given position + #[must_use] + fn camera(&self, dungeon: &Dungeon) -> Camera2D { + let cpos = dungeon.camera(); + let width = self.handle.get_render_width(); + let height = self.handle.get_render_height(); + Camera2D { + target: Vector2::from(cpos.xy()).scale_by(self.tile_size as f32), + offset: Vector2::new(width as f32 / 2.0, height as f32 / 2.0), + rotation: 0.0, + zoom: 1.0, + } } /// Clear the screen - pub fn clear(&mut self) { + fn clear(&mut self) { self.handle.clear_background(Color::BLACK); } @@ -108,16 +117,23 @@ impl<'a> FrameRenderer<'a> { /// renderer.draw_frame(&dungeon); /// ``` pub fn draw_frame(&mut self, dungeon: &Dungeon) -> crate::Result<()> { - // Clear the background to black self.clear(); - - // Draw the dungeon - self.draw_tiles(dungeon)?; - self.draw_player(&dungeon.player); - - // Draw the ui + self.draw_dungeon(dungeon)?; self.draw_ui(dungeon); + Ok(()) + } + /// Draws the dungeon, (tiles and entities) + pub fn draw_dungeon(&mut self, dungeon: &Dungeon) -> crate::Result<()> { + let camera = self.camera(dungeon); + unsafe { + ffi::BeginMode2D(camera.into()); + } + self.draw_tiles(dungeon)?; + self.draw_entities(dungeon); + unsafe { + ffi::EndMode2D(); + } Ok(()) } @@ -128,15 +144,19 @@ impl<'a> FrameRenderer<'a> { self.draw_fps(); } - /// Draw the player sprite - pub fn draw_player(&mut self, player: &Player) { - self.draw_entity(&player.entity); + /// Draws the entities on the map + pub fn draw_entities(&mut self, dungeon: &Dungeon) { + self.draw_entity(&dungeon.player.entity); } /// Draws an entity - #[expect(clippy::unused_self)] - pub fn draw_entity(&mut self, _entity: &Entity) { - // TODO: + #[expect(clippy::cast_possible_truncation)] + pub fn draw_entity(&mut self, entity: &Entity) { + let size = self.tile_size; + let x = (entity.fpos.x() * size as f32) as i32; + let y = (entity.fpos.y() * size as f32) as i32; + // TODO: per entity color + self.handle.draw_rectangle(x, y, size, size, Color::GREEN); } /// Draw dungeon tiles @@ -148,18 +168,7 @@ impl<'a> FrameRenderer<'a> { }; // caculate the starting postion on the texture to draw from - let size = self.tile_size() as f32; - let dist = VIEW_DISTANCE as f32; - let camera = Vector2::from(dungeon.camera().xy()); - let source_rec = Rectangle::new( - camera.x.sub(dist).max(0.0) * size, - camera.y.sub(dist).max(0.0) * size, - size * (dist * 2.0 + 1.0), - size * (dist * 2.0 + 1.0), - ); - - self.handle - .draw_texture_rec(&tex, source_rec, Vector2::zero(), Color::WHITE); + self.handle.draw_texture(&tex, 0, 0, Color::WHITE); // save the texture self.renderer.tiles.replace((hash, tex)); @@ -169,7 +178,7 @@ impl<'a> FrameRenderer<'a> { /// Draw tiles on a provided texture fn draw_tiles_to_tex(&mut self, floor: &Floor) -> crate::Result<RenderTexture2D> { - let size = self.tile_size(); + let size = self.tile_size; let pixels = (MAP_SIZE as i32) * size; let mut tex = self.handle |