summaryrefslogtreecommitdiff
path: root/graphics/src/render.rs
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-10-31 11:04:13 -0400
committerFreya Murphy <freya@freyacat.org>2025-10-31 11:04:13 -0400
commitd330827da265fdb6bb51ae35704509b1a2723f28 (patch)
tree479c31cc7bca23b1412cb98cb070c50507044351 /graphics/src/render.rs
parentAdd LICENSE file (diff)
downloadDungeonCrawl-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.rs141
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 {