summaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-11-10 09:24:31 -0500
committerFreya Murphy <freya@freyacat.org>2025-11-10 09:24:31 -0500
commitf9f8dbba005bd5658e4848f5272ea32524fa19da (patch)
tree76a82c57fddbf75aad60adfc04b47697167c9080 /graphics
parentmain: hallway color change (diff)
downloadDungeonCrawl-f9f8dbba005bd5658e4848f5272ea32524fa19da.tar.gz
DungeonCrawl-f9f8dbba005bd5658e4848f5272ea32524fa19da.tar.bz2
DungeonCrawl-f9f8dbba005bd5658e4848f5272ea32524fa19da.zip
graphics: fix atlas rendering offset bug, and make minimap scalable past 48px
Diffstat (limited to 'graphics')
-rw-r--r--graphics/src/render.rs170
1 files changed, 89 insertions, 81 deletions
diff --git a/graphics/src/render.rs b/graphics/src/render.rs
index 1c936bd..8e5869a 100644
--- a/graphics/src/render.rs
+++ b/graphics/src/render.rs
@@ -9,7 +9,7 @@ use raylib::{
camera::Camera2D,
color::Color,
math::{Rectangle, Vector2},
- prelude::{RaylibDraw, RaylibMode2DExt, RaylibTextureModeExt},
+ prelude::{RaylibDraw, RaylibMode2DExt, RaylibScissorModeExt, RaylibTextureModeExt},
texture::{RaylibTexture2D, RenderTexture2D, Texture2D},
};
@@ -269,7 +269,7 @@ impl Renderer {
where
R: RaylibDraw + RaylibMode2DExt,
{
- let camera = render_camera(dungeon);
+ let camera = dungeon.render_camera();
let mut rc = r.begin_mode2D(camera);
self.draw_bg_tilemap(&mut rc);
self.draw_entities(&mut rc, dungeon);
@@ -425,8 +425,8 @@ impl Renderer {
{
r.draw_tilemap(
&self.tilemap_fg,
- 0,
- 0,
+ 0u16,
+ 0u16,
TILE_SIZE / TEXTURE_SIZE,
WALL_HEIGHT,
);
@@ -437,7 +437,7 @@ impl Renderer {
where
R: RaylibDraw,
{
- r.draw_tilemap(&self.tilemap_bg, 0, 0, TILE_SIZE / TEXTURE_SIZE, 0);
+ r.draw_tilemap(&self.tilemap_bg, 0u16, 0u16, TILE_SIZE / TEXTURE_SIZE, 0);
}
/// Draws the entities on the map
@@ -469,12 +469,12 @@ impl Renderer {
Direction::West => (1, 1),
};
let dest_rec = rect! {
- fx * size - size/2.0,
- fy * size - size/2.0,
+ fx * size,
+ fy * size,
size,
size,
};
- r.draw_inv_atlas(texture, (ax, ay), dest_rec.x, dest_rec.y, size, 0.0);
+ r.draw_atlas(texture, (ax, ay), dest_rec.x, dest_rec.y, size, 0.0);
if self.debug {
r.draw_rectangle_lines_ex(dest_rec, 1.0, Color::YELLOW);
@@ -503,7 +503,7 @@ impl Renderer {
/// Draw in game minimap
fn draw_minimap<R>(&self, r: &mut R, dungeon: &Dungeon)
where
- R: RaylibDraw,
+ R: RaylibDraw + RaylibScissorModeExt,
{
const Y: u16 = UI_PADDING;
@@ -511,23 +511,47 @@ impl Renderer {
const TEXT_X: u16 = UI_PADDING;
self.draw_text_vertical(r, b"MAP", TEXT_X, Y);
- // Draw minimap in top left of UI bar
+ // Base coords for the minimap
const MINIMAP_X: u16 = TEXT_X + FONT_SIZE + UI_PADDING;
- r.draw_tilemap(&self.tilemap_mm, MINIMAP_X, Y, 1, 0);
+ const MAX_MINIMAP_SIZE: u16 = FONT_SIZE * 3;
+ const EXTRA_PIXELS: u16 = MAP_SIZE.saturating_sub(MAX_MINIMAP_SIZE) + 1;
- // Draw minimap entity's
- let mut draw_dot = |pos: Pos, color| {
- let (x, y) = pos.xy();
- r.draw_pixel((MINIMAP_X + x).into(), (Y + y).into(), color);
- };
+ // Get the real coords of the minimap (offset)
+ let offset_x = (dungeon.player.entity.pos.x() / (MAP_SIZE / EXTRA_PIXELS))
+ .saturating_sub(MAX_MINIMAP_SIZE / 2);
+ let offset_y = (dungeon.player.entity.pos.y() / (MAP_SIZE / EXTRA_PIXELS))
+ .saturating_sub(MAX_MINIMAP_SIZE / 2);
+ let minimap_x = MINIMAP_X.cast_signed() - offset_x.cast_signed();
+ let minimap_y = Y.cast_signed() - offset_y.cast_signed();
- // Draw enemy dots
- for enemy in &dungeon.enemies {
- draw_dot(enemy.pos, Color::RED);
- }
+ // Draw in scissor mode incase the map size is too big
+ {
+ let mut rs = r.begin_scissor_mode(
+ MINIMAP_X.into(),
+ Y.into(),
+ MAX_MINIMAP_SIZE.into(),
+ MAX_MINIMAP_SIZE.into(),
+ );
+ rs.draw_tilemap(&self.tilemap_mm, minimap_x, minimap_y, 1, 0);
+
+ // Draw minimap entity's
+ let mut draw_dot = |pos: Pos, color| {
+ let (x, y) = pos.xy();
+ rs.draw_pixel(
+ (minimap_x + x.cast_signed()).into(),
+ (minimap_y + y.cast_signed()).into(),
+ color,
+ );
+ };
+
+ // Draw enemy dots
+ for enemy in &dungeon.enemies {
+ draw_dot(enemy.pos, Color::RED);
+ }
- // Draw player dot
- draw_dot(dungeon.player.entity.pos, Color::LIME);
+ // Draw player dot
+ draw_dot(dungeon.player.entity.pos, Color::LIME);
+ }
}
/// Draws the player's inventory
@@ -558,7 +582,7 @@ impl Renderer {
let slot_x = SLOTS_X + SLOT_LEN * idx;
// Draw slot container
- r.draw_inv_atlas(
+ r.draw_atlas(
&self.textures.atlas,
ATLAS_INV_CONTAINER,
slot_x,
@@ -597,7 +621,7 @@ impl Renderer {
let damage = 0; // TODO: calc damage
const TEXT_WIDTH: u16 = FONT_SIZE * 3 + UI_PADDING;
- const ICON_WIDTH: u16 = FONT_SIZE + UI_PADDING;
+ const ICON_WIDTH: u16 = FONT_SIZE;
const ICON_X: u16 = RENDER_WIDTH - TEXT_WIDTH - ICON_WIDTH;
const TEXT_X: u16 = RENDER_WIDTH - TEXT_WIDTH;
@@ -606,9 +630,9 @@ impl Renderer {
r.draw_atlas(
&self.textures.atlas,
ATLAS_HEART_ICON,
- ICON_X + UI_PADDING,
- HEART_Y + UI_PADDING,
- FONT_SIZE,
+ ICON_X,
+ HEART_Y,
+ ICON_WIDTH,
0.0,
);
draw_text!(self, r, TEXT_X, HEART_Y, "x{health:02}");
@@ -618,9 +642,9 @@ impl Renderer {
r.draw_atlas(
&self.textures.atlas,
ATLAS_DAMAGE_ICON,
- ICON_X + UI_PADDING,
- DAMAGE_Y + UI_PADDING,
- FONT_SIZE,
+ ICON_X,
+ DAMAGE_Y,
+ ICON_WIDTH,
0.0,
);
draw_text!(self, r, TEXT_X, DAMAGE_Y, "x{damage:02}");
@@ -696,7 +720,7 @@ impl Renderer {
}
let ax = char % 16;
let ay = (char - 32) / 16;
- r.draw_inv_atlas(
+ r.draw_atlas(
&self.textures.font,
(ax.into(), ay.into()),
x,
@@ -707,30 +731,35 @@ impl Renderer {
}
}
-/// Returns the Raylib Camera setup with needed 2D position/transforms
-fn render_camera(dungeon: &Dungeon) -> Camera2D {
- /// The minimum position the camera is allowed to go
- const CAMERA_MIN: Vector2 = vec2! {
- RENDER_WIDTH/2, RENDER_HEIGHT/2 - UI_HEIGHT/2,
- };
- /// The maximum position the camera is allowed to go
- const CAMERA_MAX: Vector2 = vec2! {
- MAP_SIZE * TILE_SIZE - RENDER_WIDTH/2,
- MAP_SIZE * TILE_SIZE - RENDER_HEIGHT/2 - UI_HEIGHT/2,
- };
+trait DungeonExt {
+ fn render_camera(&self) -> Camera2D;
+}
+impl DungeonExt for Dungeon {
+ /// Returns the Raylib Camera setup with needed 2D position/transforms
+ fn render_camera(&self) -> Camera2D {
+ /// The minimum position the camera is allowed to go
+ const CAMERA_MIN: Vector2 = vec2! {
+ RENDER_WIDTH/2, RENDER_HEIGHT/2 - UI_HEIGHT/2,
+ };
+ /// The maximum position the camera is allowed to go
+ const CAMERA_MAX: Vector2 = vec2! {
+ MAP_SIZE * TILE_SIZE - RENDER_WIDTH/2,
+ MAP_SIZE * TILE_SIZE - RENDER_HEIGHT/2 - UI_HEIGHT/2,
+ };
- let pos = dungeon.camera();
- Camera2D {
- target: Vector2::from(pos.xy())
- .scale_by(TILE_SIZE.into())
- .max(CAMERA_MIN)
- .min(CAMERA_MAX),
- offset: vec2! {
- RENDER_WIDTH/2,
- RENDER_HEIGHT/2 + UI_HEIGHT/2,
- },
- rotation: 0.0,
- zoom: 1.0,
+ let pos = self.camera();
+ Camera2D {
+ target: Vector2::from(pos.xy())
+ .scale_by(TILE_SIZE.into())
+ .max(CAMERA_MIN)
+ .min(CAMERA_MAX),
+ offset: vec2! {
+ RENDER_WIDTH/2 - TILE_SIZE/2,
+ RENDER_HEIGHT/2 - TILE_SIZE/2 + UI_HEIGHT/2,
+ },
+ rotation: 0.0,
+ zoom: 1.0,
+ }
}
}
@@ -770,8 +799,8 @@ where
TEXTURE_SIZE,
};
let dest_rec = rect! {
- x.into(),
- y.into(),
+ x.into() + size_into/2.0,
+ y.into() + size_into/2.0,
size_into,
size_into,
};
@@ -789,33 +818,12 @@ where
);
}
- /// Draw in INV element from an atlas
- fn draw_inv_atlas(
- &mut self,
- tex: &Texture2D,
- (ax, ay): (u16, u16),
- x: impl Into<f32>,
- y: impl Into<f32>,
- size: impl Into<f32>,
- rotation: impl Into<f32>,
- ) {
- let size_into = size.into();
- self.draw_atlas(
- tex,
- (ax, ay),
- x.into() + size_into / 2.0,
- y.into() + size_into / 2.0,
- size_into,
- rotation,
- );
- }
-
/// Draw dungeon tiles helper function
fn draw_tilemap(
&mut self,
tex: &RenderTexture2D,
- x: u16,
- y: u16,
+ x: impl Into<i32>,
+ y: impl Into<i32>,
scale: u16,
offset: u16,
) {
@@ -828,8 +836,8 @@ where
-height.cast_signed(),
};
let dest_rec = rect! {
- x,
- y.cast_signed() - (offset * scale).cast_signed(),
+ x.into(),
+ y.into() - (offset * scale) as i32,
width * scale,
height * scale,
};