diff options
| author | Freya Murphy <freya@freyacat.org> | 2025-10-31 11:04:13 -0400 |
|---|---|---|
| committer | Freya Murphy <freya@freyacat.org> | 2025-10-31 11:04:13 -0400 |
| commit | d330827da265fdb6bb51ae35704509b1a2723f28 (patch) | |
| tree | 479c31cc7bca23b1412cb98cb070c50507044351 /graphics/src/render.rs | |
| parent | Add LICENSE file (diff) | |
| download | DungeonCrawl-d330827da265fdb6bb51ae35704509b1a2723f28.tar.gz DungeonCrawl-d330827da265fdb6bb51ae35704509b1a2723f28.tar.bz2 DungeonCrawl-d330827da265fdb6bb51ae35704509b1a2723f28.zip | |
graphics: add health/inventory ui rendering
Diffstat (limited to '')
| -rw-r--r-- | graphics/src/render.rs | 141 |
1 files changed, 129 insertions, 12 deletions
diff --git a/graphics/src/render.rs b/graphics/src/render.rs index b6af7c7..499301c 100644 --- a/graphics/src/render.rs +++ b/graphics/src/render.rs @@ -2,12 +2,12 @@ //! the game, with each frame represented by a `Renderer` and //! frame specific information in `FrameInfo`. -/// The (prefered) view distance of the game -const VIEW_DISTANCE: i32 = 5; - use std::{cell::RefCell, ops::Div, rc::Rc}; -use dungeon::{Direction, Dungeon, Entity, EntityKind, FPos, Floor, MAP_SIZE, Pos, Tile}; +use dungeon::{ + Direction, Dungeon, Entity, EntityKind, FPos, Floor, MAP_SIZE, PLAYER_FULL_HEALTH, + Player, Pos, Tile, +}; use raylib::{ RaylibThread, camera::Camera2D, @@ -22,6 +22,17 @@ use raylib::{ use crate::assets::{AtlasTexture, BASE_TILE_SIZE, ImageData, WALL_HEIGHT}; +/// The (prefered) view distance of the game +const VIEW_DISTANCE: i32 = 5; + +/// Full source rec for any texture +const FULL_SOURCE_REC: Rectangle = Rectangle { + x: 0.0, + y: 0.0, + width: BASE_TILE_SIZE as f32, + height: BASE_TILE_SIZE as f32, +}; + /// The `FrameInfo` struct stores information used during a single frame #[derive(Clone, Copy, Debug)] struct FrameInfo { @@ -285,12 +296,118 @@ where } /// Draws player HP, inventory, and floor number - pub fn draw_ui(&mut self, _dungeon: &Dungeon) { + pub fn draw_ui(&mut self, dungeon: &Dungeon) { + // Draw core ui components + self.draw_health(&dungeon.player); + self.draw_inventory(&dungeon.player); + + // Draw debug info #[cfg(feature = "debug")] - // Draw fps (debug only) + self.draw_debug_ui(dungeon); + } + + fn draw_health(&mut self, player: &Player) { + let health = player.entity.health.unwrap_or(0); + let hearts = PLAYER_FULL_HEALTH.div_ceil(2); + let mut full_hearts = health / 2; + let mut half_hearts = health % 2; + let mut empty_hearts = hearts.saturating_sub(full_hearts + half_hearts); + + let size = self.info.tile_size.div(2).max(BASE_TILE_SIZE); + let y = BASE_TILE_SIZE; + let mut x = BASE_TILE_SIZE; + loop { + let tex = if full_hearts > 0 { + full_hearts -= 1; + &self.state.image.heart_full + } else if half_hearts > 0 { + half_hearts -= 1; + &self.state.image.heart_half + } else if empty_hearts > 0 { + empty_hearts -= 1; + &self.state.image.heart_empty + } else { + break; + }; + + let dest_rec = Rectangle { + x: x as f32, + y: y as f32, + width: size as f32, + height: size as f32, + }; + self.handle.draw_texture_pro( + tex, + FULL_SOURCE_REC, + dest_rec, + Vector2::zero(), + 0.0, + Color::WHITE, + ); + x += size; + } + } + + fn draw_inventory(&mut self, player: &Player) { + let len = i32::try_from(player.inventory.len()).unwrap_or(0); + + // size of the inv blocks + let size = self.info.tile_size.div(2).max(BASE_TILE_SIZE); + + // position of the inv blocks + let y = self.info.height - size; + let mut x = self.info.width / 2 - (size * len / 2); + + // size of font for number index + let font_size = size / 3; + let font_offset = font_size * 2; + + for (idx, item) in player.inventory.iter().enumerate() { + let dest_rec = Rectangle { + x: x as f32, + y: y as f32, + width: size as f32, + height: size as f32, + }; + self.draw_ui_atlas( + AtlasTexture::InvBottomLayer, + x as f32, + y as f32, + size as f32, + ); + let tex = self.state.image.get_item_texture(item); + self.handle.draw_texture_pro( + tex, + FULL_SOURCE_REC, + dest_rec, + Vector2::zero(), + 0.0, + Color::WHITE, + ); + self.draw_ui_atlas(AtlasTexture::InvTopLayer, x as f32, y as f32, size as f32); + self.handle.draw_text( + &format!("{}", idx + 1), + x + font_offset + font_offset / 5, + y + font_offset, + font_size, + Color::WHITE, + ); + x += size; + } + } + + /// Draws debug information ontop of other UI elements + /// Called by default if `debug` featue is enabled + pub fn draw_debug_ui(&mut self, _dungeon: &Dungeon) { self.draw_fps(); } + /// Draw FPS counter (debug) + fn draw_fps(&mut self) { + let fps_str = format!("{}", self.info.fps); + self.handle.draw_text(&fps_str, 10, 10, 30, Color::YELLOW); + } + /// Draws the entities on the map fn draw_entities(&mut self, dungeon: &Dungeon) { self.draw_entity(&dungeon.player.entity); @@ -324,6 +441,12 @@ where self.handle.draw_tilemap(tex, size, offset); } + /// Draw an atlas texture index (with ui offset applied) + fn draw_ui_atlas(&mut self, tex: AtlasTexture, x: f32, y: f32, size: f32) { + let half_size = size / 2.0; + self.draw_atlas(tex, x + half_size, y + half_size, size, 0.0); + } + /// Draw an atlas texture index fn draw_atlas(&mut self, tex: AtlasTexture, x: f32, y: f32, size: f32, rotation: f32) { let source_rec = Rectangle { @@ -351,12 +474,6 @@ where Color::WHITE, ); } - - /// Draw FPS counter - fn draw_fps(&mut self) { - let fps_str = format!("{}", self.info.fps); - self.handle.draw_text(&fps_str, 10, 10, 30, Color::YELLOW); - } } trait Vector2Ext { |