diff options
| -rw-r--r-- | dungeon/src/pos.rs | 15 | ||||
| -rw-r--r-- | game/Cargo.toml | 3 | ||||
| -rw-r--r-- | game/src/main.rs | 5 | ||||
| -rw-r--r-- | graphics/Cargo.toml | 1 | ||||
| -rw-r--r-- | graphics/src/lib.rs | 5 | ||||
| -rw-r--r-- | graphics/src/render.rs | 122 |
6 files changed, 123 insertions, 28 deletions
diff --git a/dungeon/src/pos.rs b/dungeon/src/pos.rs index a7b6080..d31ba95 100644 --- a/dungeon/src/pos.rs +++ b/dungeon/src/pos.rs @@ -10,7 +10,10 @@ use rand::{ distr::{Distribution, StandardUniform}, }; -use std::ops::{AddAssign, SubAssign}; +use std::{ + fmt::Display, + ops::{AddAssign, SubAssign}, +}; use crate::{MAP_SIZE_USIZE, map::MAP_SIZE}; @@ -54,6 +57,16 @@ impl Direction { rand::random() } } +impl Display for Direction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::North => write!(f, "NORTH"), + Self::South => write!(f, "SOUTH"), + Self::East => write!(f, "EAST"), + Self::West => write!(f, "WEST"), + } + } +} impl Distribution<Direction> for StandardUniform { fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Direction { diff --git a/game/Cargo.toml b/game/Cargo.toml index 2cfa795..2792e83 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -15,7 +15,6 @@ graphics.workspace = true workspace = true [features] -default = ["debug"] -debug = ["graphics/debug"] +default = [] wayland = ["graphics/wayland"] sdl = ["graphics/sdl"] diff --git a/game/src/main.rs b/game/src/main.rs index 1c76abc..ae92e12 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -11,6 +11,11 @@ fn main() -> Result<()> { while window.is_open() { // TODO update game state + // Handle keyboard input + if window.is_key_pressed(KeyCode::KEY_F3) { + window.toggle_debug(); + } + for enemy in dungeon.enemies.iter_mut() { enemy.handle_movement( dungeon.player.entity.pos, diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 050c314..6f3be4e 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -16,6 +16,5 @@ workspace = true [features] default = [] -debug = [] wayland = ["sdl", "raylib/wayland"] sdl = ["raylib/sdl"] diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 81ac16e..a9567eb 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -87,6 +87,11 @@ impl Window { .draw_frame(self.handle.get_mut(), &self.thread, dungeon); } + /// Toggles the debug UI + pub fn toggle_debug(&mut self) { + self.renderer.toggle_debug(); + } + /// Returns the per frame delta time pub fn delta_time(&self) -> f32 { self.handle.borrow().get_frame_time() diff --git a/graphics/src/render.rs b/graphics/src/render.rs index 95aecb8..aaa9983 100644 --- a/graphics/src/render.rs +++ b/graphics/src/render.rs @@ -39,6 +39,14 @@ macro_rules! vec2 { }; } +macro_rules! draw_text { + ($self:ident, $r:expr, $x:expr, $y:expr, $buffer:expr, $offset:expr, $($arg:tt)*) => {{ + let mut buffer = *$buffer; + let _ = write!(&mut buffer[$offset..], $($arg)*); + $self.draw_text($r, &buffer, $x, $y); + }}; +} + /// The baseline size of all ingame sprites and tile textures const BASE_TEXTURE_SIZE: u16 = 16; @@ -128,6 +136,10 @@ pub struct Renderer { width: u16, /// Render height of the current frame height: u16, + /// The current frame + frame: u64, + /// Show debug UI + debug: bool, } impl Renderer { pub fn new(handle: &mut RaylibHandle, thread: &RaylibThread) -> crate::Result<Self> { @@ -150,9 +162,15 @@ impl Renderer { fps: 0, width: 0, height: 0, + frame: 0, + debug: false, }) } + pub fn toggle_debug(&mut self) { + self.debug = !self.debug; + } + pub fn draw_frame( &mut self, handle: &mut RaylibHandle, @@ -182,6 +200,8 @@ impl Renderer { let pixels = size.div(dist).max(BASE_TEXTURE_SIZE); 1 << (u16::BITS - pixels.leading_zeros()) }; + // Update frame counter + self.frame += 1; } /// Returns the Raylib Camera setup with needed 2D position/transforms @@ -392,6 +412,10 @@ impl Renderer { 0.0, Color::WHITE, ); + + if self.debug { + r.draw_rectangle_lines_ex(dest_rec, 1.0, Color::YELLOW); + } } /// Returns the known UI height for this frame @@ -417,14 +441,15 @@ impl Renderer { // Draw UI base rect r.draw_rectangle_ext(0, 0, self.width, self.get_ui_height(), Color::BLACK); + if self.debug { + self.draw_debug_ui(r, dungeon); + return; + } + // Draw core ui components self.draw_minimap(r, dungeon); self.draw_inventory(r, &dungeon.player); self.draw_stats(r, &dungeon.player); - - // Draw debug info - #[cfg(feature = "debug")] - self.draw_debug_ui(r); } /// Draw in game minimap @@ -551,11 +576,7 @@ impl Renderer { let icon_x = stats_x; let text_x = icon_x + icon_width; - // text buffer - let mut buffer = [b'x', b'0', b'0']; - // draw health - let _ = write!(&mut buffer[1..], "{health:02}"); let heart_y = padding; r.draw_inv_atlas( &self.textures.atlas, @@ -565,10 +586,9 @@ impl Renderer { icon_width, 0.0, ); - self.draw_text(r, &buffer, text_x, heart_y + padding); + draw_text!(self, r, text_x, heart_y + padding, b"x00", 1, "{health:02}"); // draw damage - let _ = write!(&mut buffer[1..], "{damage:02}"); let damage_y = heart_y + font_size + padding; r.draw_inv_atlas( &self.textures.atlas, @@ -578,27 +598,81 @@ impl Renderer { icon_width, 0.0, ); - self.draw_text(r, &buffer, text_x, damage_y + padding); + draw_text!( + self, + r, + text_x, + damage_y + padding, + b"x00", + 1, + "{damage:02}" + ); } /// Draws debug information ontop of other UI elements - /// Called by default if `debug` featue is enabled - #[cfg(feature = "debug")] - fn draw_debug_ui<R>(&self, r: &mut R) + fn draw_debug_ui<R>(&self, r: &mut R, dungeon: &Dungeon) where R: RaylibDraw, { - self.draw_fps(r); - } + let padding = self.get_ui_padding(); + let font_size = self.get_ui_font_size(); + let player = &dungeon.player; - /// Draw FPS counter (debug) - #[cfg(feature = "debug")] - fn draw_fps<R>(&self, r: &mut R) - where - R: RaylibDraw, - { - let fps_str = format!("{}", self.fps); - r.draw_text(&fps_str, 10, 10, 30, Color::YELLOW); + // X Positions + let col1 = padding; + let col2 = padding + font_size * 10; + + // Y Positions + let row1 = padding; + let row2 = row1 + font_size; + let row3 = row2 + font_size; + + // Draw FPS + draw_text!(self, r, col1, row1, b"FPS ", 4, "{}", self.fps); + + // Draw Player position + let (x, y) = &player.entity.pos.xy(); + draw_text!(self, r, col1, row2, b"POS 00,00", 4, "{x:02},{y:02}"); + + // Draw Player direction + let dir = &player.entity.dir; + draw_text!(self, r, col1, row3, b"DIR ", 4, "{dir}"); + + // Draw Player Seed + let seed = &dungeon.floor.seed(); + draw_text!( + self, + r, + col2, + row1, + b" SEED 0x0000000000000000", + 8, + "{seed:X}" + ); + + // Draw Dungeon Hash + let hash = dungeon.floor.hash(); + draw_text!( + self, + r, + col2, + row2, + b" HASH 0x0000000000000000", + 8, + "{hash:X}" + ); + + // Draw current frame number + let frame = &self.frame; + draw_text!( + self, + r, + col2, + row3, + b"FRAME ", + 6, + "{frame}" + ); } /// Draws vertical text |