summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graphics/src/render.rs107
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