fix: bigger UI panels with more spacing between text lines
Character panel: - Width 44 -> 52, height 44 -> 62 - Text rows spaced 8 apart (was 6) — no more squished text - HP/XP bars 38 wide (was 32) - Stats with double space between pairs - Inventory section at bottom with more room HUD bar: - Height 18 -> 28 - Rows at y_top+2, +12, +22 (was +1, +7, +13) Inventory overlay: - Slots 12x10 (was 8x6), gap 3 (was 2) - Panel auto-sizes larger - Click hitboxes in main.rs updated to match Fixed depth_shown_in_hud test for new HUD height. All 171 tests + 14 scenarios pass.
This commit is contained in:
+10
-10
@@ -369,11 +369,11 @@ fn run_gpu_mode<R: GpuRenderer>(title: &str) {
|
|||||||
|
|
||||||
let cols = 4i32;
|
let cols = 4i32;
|
||||||
let rows = 2i32;
|
let rows = 2i32;
|
||||||
let slot_w = 8i32;
|
let slot_w = 12i32;
|
||||||
let slot_h = 6i32;
|
let slot_h = 10i32;
|
||||||
let gap = 2i32;
|
let gap = 3i32;
|
||||||
let panel_w = cols * slot_w + (cols + 1) * gap + 4;
|
let panel_w = cols * slot_w + (cols + 1) * gap + 4;
|
||||||
let panel_h = rows * slot_h + (rows + 1) * gap + 20;
|
let panel_h = rows * slot_h + (rows + 1) * gap + 28;
|
||||||
let px_start = (ui_w - panel_w) / 2;
|
let px_start = (ui_w - panel_w) / 2;
|
||||||
let py_start = (ui_h - panel_h) / 2;
|
let py_start = (ui_h - panel_h) / 2;
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ fn run_gpu_mode<R: GpuRenderer>(title: &str) {
|
|||||||
for col in 0..cols {
|
for col in 0..cols {
|
||||||
let idx = (row * cols + col) as usize;
|
let idx = (row * cols + col) as usize;
|
||||||
let sx = px_start + gap + col * (slot_w + gap) + 2;
|
let sx = px_start + gap + col * (slot_w + gap) + 2;
|
||||||
let sy = py_start + 10 + row * (slot_h + gap) + gap;
|
let sy = py_start + 14 + row * (slot_h + gap) + gap;
|
||||||
if mouse_ui_x >= sx
|
if mouse_ui_x >= sx
|
||||||
&& mouse_ui_x < sx + slot_w
|
&& mouse_ui_x < sx + slot_w
|
||||||
&& mouse_ui_y >= sy
|
&& mouse_ui_y >= sy
|
||||||
@@ -404,11 +404,11 @@ fn run_gpu_mode<R: GpuRenderer>(title: &str) {
|
|||||||
|
|
||||||
let cols = 4i32;
|
let cols = 4i32;
|
||||||
let rows = 2i32;
|
let rows = 2i32;
|
||||||
let slot_w = 8i32;
|
let slot_w = 12i32;
|
||||||
let slot_h = 6i32;
|
let slot_h = 10i32;
|
||||||
let gap = 2i32;
|
let gap = 3i32;
|
||||||
let panel_w = cols * slot_w + (cols + 1) * gap + 4;
|
let panel_w = cols * slot_w + (cols + 1) * gap + 4;
|
||||||
let panel_h = rows * slot_h + (rows + 1) * gap + 20;
|
let panel_h = rows * slot_h + (rows + 1) * gap + 28;
|
||||||
let px_start = (ui_w - panel_w) / 2;
|
let px_start = (ui_w - panel_w) / 2;
|
||||||
let py_start = (ui_h - panel_h) / 2;
|
let py_start = (ui_h - panel_h) / 2;
|
||||||
|
|
||||||
@@ -416,7 +416,7 @@ fn run_gpu_mode<R: GpuRenderer>(title: &str) {
|
|||||||
for col in 0..cols {
|
for col in 0..cols {
|
||||||
let idx = (row * cols + col) as usize;
|
let idx = (row * cols + col) as usize;
|
||||||
let sx = px_start + gap + col * (slot_w + gap) + 2;
|
let sx = px_start + gap + col * (slot_w + gap) + 2;
|
||||||
let sy = py_start + 10 + row * (slot_h + gap) + gap;
|
let sy = py_start + 14 + row * (slot_h + gap) + gap;
|
||||||
if mouse_ui_x >= sx
|
if mouse_ui_x >= sx
|
||||||
&& mouse_ui_x < sx + slot_w
|
&& mouse_ui_x < sx + slot_w
|
||||||
&& mouse_ui_y >= sy
|
&& mouse_ui_y >= sy
|
||||||
|
|||||||
+37
-34
@@ -334,8 +334,8 @@ impl UiLayer {
|
|||||||
player: Option<&Entity>,
|
player: Option<&Entity>,
|
||||||
player_state: &crate::entity::player::Player,
|
player_state: &crate::entity::player::Player,
|
||||||
) {
|
) {
|
||||||
let w = 44i32;
|
let w = 52i32;
|
||||||
let h = 44i32;
|
let h = 62i32;
|
||||||
let bg = [22u8, 26, 38];
|
let bg = [22u8, 26, 38];
|
||||||
let border = [160u8, 180, 255];
|
let border = [160u8, 180, 255];
|
||||||
let title = [220u8, 230, 255];
|
let title = [220u8, 230, 255];
|
||||||
@@ -375,11 +375,11 @@ impl UiLayer {
|
|||||||
|
|
||||||
let title_text = "STATUS";
|
let title_text = "STATUS";
|
||||||
let tx = start_x + (w - Self::text_width(title_text)) / 2;
|
let tx = start_x + (w - Self::text_width(title_text)) / 2;
|
||||||
self.draw_text(tx, start_y + 1, title_text, title, 255);
|
self.draw_text(tx, start_y + 2, title_text, title, 255);
|
||||||
|
|
||||||
if let Some(p) = player {
|
if let Some(p) = player {
|
||||||
let hp_ratio = (p.health / p.max_health).clamp(0.0, 1.0);
|
let hp_ratio = (p.health / p.max_health).clamp(0.0, 1.0);
|
||||||
let hp_filled = (hp_ratio * 32.0).round() as i32;
|
let hp_filled = (hp_ratio * 38.0).round() as i32;
|
||||||
let bar_color = if hp_ratio > 0.6 {
|
let bar_color = if hp_ratio > 0.6 {
|
||||||
[80, 240, 80]
|
[80, 240, 80]
|
||||||
} else if hp_ratio > 0.3 {
|
} else if hp_ratio > 0.3 {
|
||||||
@@ -387,56 +387,59 @@ impl UiLayer {
|
|||||||
} else {
|
} else {
|
||||||
[255, 60, 60]
|
[255, 60, 60]
|
||||||
};
|
};
|
||||||
self.draw_text(start_x + 2, start_y + 7, "HP", fg, 255);
|
self.draw_text(start_x + 3, start_y + 10, "HP", fg, 255);
|
||||||
for i in 0..32 {
|
for i in 0..38 {
|
||||||
let ch = if i < hp_filled { '#' } else { '-' };
|
let ch = if i < hp_filled { '#' } else { '-' };
|
||||||
let c = if i < hp_filled {
|
let c = if i < hp_filled {
|
||||||
bar_color
|
bar_color
|
||||||
} else {
|
} else {
|
||||||
[80, 80, 100]
|
[80, 80, 100]
|
||||||
};
|
};
|
||||||
self.set(start_x + 10 + i, start_y + 7, ch, c, bg);
|
self.set(start_x + 10 + i, start_y + 10, ch, c, bg);
|
||||||
}
|
}
|
||||||
let hp_text = format!("{}/{} LV:{}", p.health as i32, p.max_health as i32, p.level);
|
let hp_text = format!(
|
||||||
self.draw_text(start_x + 2, start_y + 13, &hp_text, fg, 255);
|
"{}/{} LV:{}",
|
||||||
|
p.health as i32, p.max_health as i32, p.level
|
||||||
|
);
|
||||||
|
self.draw_text(start_x + 3, start_y + 18, &hp_text, fg, 255);
|
||||||
|
|
||||||
let xp_ratio = (p.xp as f32 / p.xp_to_level() as f32).clamp(0.0, 1.0);
|
let xp_ratio = (p.xp as f32 / p.xp_to_level() as f32).clamp(0.0, 1.0);
|
||||||
let xp_filled = (xp_ratio * 32.0).round() as i32;
|
let xp_filled = (xp_ratio * 38.0).round() as i32;
|
||||||
self.draw_text(start_x + 2, start_y + 19, "XP", fg, 255);
|
self.draw_text(start_x + 3, start_y + 26, "XP", fg, 255);
|
||||||
for i in 0..32 {
|
for i in 0..38 {
|
||||||
let ch = if i < xp_filled { '#' } else { '-' };
|
let ch = if i < xp_filled { '#' } else { '-' };
|
||||||
let c = if i < xp_filled {
|
let c = if i < xp_filled {
|
||||||
[80, 160, 240]
|
[80, 160, 240]
|
||||||
} else {
|
} else {
|
||||||
[60, 60, 80]
|
[60, 60, 80]
|
||||||
};
|
};
|
||||||
self.set(start_x + 10 + i, start_y + 19, ch, c, bg);
|
self.set(start_x + 10 + i, start_y + 26, ch, c, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
let stats = format!("STR:{} AGI:{}", p.strength, p.agility);
|
let stats = format!("STR:{} AGI:{}", p.strength, p.agility);
|
||||||
self.draw_text(start_x + 2, start_y + 25, &stats, dim, 255);
|
self.draw_text(start_x + 3, start_y + 36, &stats, dim, 255);
|
||||||
let stats2 = format!("TOU:{} WIL:{}", p.toughness, p.willpower);
|
let stats2 = format!("TOU:{} WIL:{}", p.toughness, p.willpower);
|
||||||
self.draw_text(start_x + 2, start_y + 31, &stats2, dim, 255);
|
self.draw_text(start_x + 3, start_y + 44, &stats2, dim, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
let inv_title = "INV:";
|
let inv_title = "INVENTORY";
|
||||||
self.draw_text(start_x + 2, start_y + 37, inv_title, fg, 255);
|
self.draw_text(start_x + 3, start_y + 52, inv_title, fg, 255);
|
||||||
let mut ix = start_x + 14;
|
let mut ix = start_x + 3;
|
||||||
for item in player_state.inventory.iter().take(8) {
|
for item in player_state.inventory.iter().take(8) {
|
||||||
if ix + 1 >= start_x + w - 1 {
|
if ix + 2 >= start_x + w - 2 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let [ch1, ch2] = item.display_glyph();
|
let [ch1, ch2] = item.display_glyph();
|
||||||
let col = item.color();
|
let col = item.color();
|
||||||
self.set(ix, start_y + 38, ch1, col, bg);
|
self.set(ix, start_y + 58, ch1, col, bg);
|
||||||
self.set(
|
self.set(
|
||||||
ix + 1,
|
ix + 1,
|
||||||
start_y + 38,
|
start_y + 58,
|
||||||
ch2,
|
ch2,
|
||||||
[col[0] / 2, col[1] / 2, col[2] / 2],
|
[col[0] / 2, col[1] / 2, col[2] / 2],
|
||||||
bg,
|
bg,
|
||||||
);
|
);
|
||||||
ix += 3;
|
ix += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = if let Some(p) = player {
|
let status = if let Some(p) = player {
|
||||||
@@ -482,11 +485,11 @@ impl UiLayer {
|
|||||||
|
|
||||||
let cols = 4i32;
|
let cols = 4i32;
|
||||||
let rows = 2i32;
|
let rows = 2i32;
|
||||||
let slot_w = 8i32;
|
let slot_w = 12i32;
|
||||||
let slot_h = 6i32;
|
let slot_h = 10i32;
|
||||||
let gap = 2i32;
|
let gap = 3i32;
|
||||||
let panel_w = cols * slot_w + (cols + 1) * gap + 4;
|
let panel_w = cols * slot_w + (cols + 1) * gap + 4;
|
||||||
let panel_h = rows * slot_h + (rows + 1) * gap + 20;
|
let panel_h = rows * slot_h + (rows + 1) * gap + 28;
|
||||||
|
|
||||||
let px_start = (screen_w as i32 - panel_w) / 2;
|
let px_start = (screen_w as i32 - panel_w) / 2;
|
||||||
let py_start = (screen_h as i32 - panel_h) / 2;
|
let py_start = (screen_h as i32 - panel_h) / 2;
|
||||||
@@ -538,7 +541,7 @@ impl UiLayer {
|
|||||||
for col in 0..cols {
|
for col in 0..cols {
|
||||||
let idx = (row * cols + col) as usize;
|
let idx = (row * cols + col) as usize;
|
||||||
let sx = px_start + gap + col * (slot_w + gap) + 2;
|
let sx = px_start + gap + col * (slot_w + gap) + 2;
|
||||||
let sy = py_start + 10 + row * (slot_h + gap) + gap;
|
let sy = py_start + 14 + row * (slot_h + gap) + gap;
|
||||||
|
|
||||||
for y in 0..slot_h {
|
for y in 0..slot_h {
|
||||||
for x in 0..slot_w {
|
for x in 0..slot_w {
|
||||||
@@ -569,7 +572,7 @@ impl UiLayer {
|
|||||||
let [ch1, ch2] = item.display_glyph();
|
let [ch1, ch2] = item.display_glyph();
|
||||||
let col = item.color();
|
let col = item.color();
|
||||||
let cx = sx + slot_w / 2 - 1;
|
let cx = sx + slot_w / 2 - 1;
|
||||||
let cy = sy + slot_h / 2 - 1;
|
let cy = sy + slot_h / 2 - 2;
|
||||||
self.set(cx, cy, ch1, col, slot_bg);
|
self.set(cx, cy, ch1, col, slot_bg);
|
||||||
self.set(
|
self.set(
|
||||||
cx + 1,
|
cx + 1,
|
||||||
@@ -683,11 +686,11 @@ impl UiLayer {
|
|||||||
.map(|i| i.display_string())
|
.map(|i| i.display_string())
|
||||||
.unwrap_or(" ".to_string());
|
.unwrap_or(" ".to_string());
|
||||||
|
|
||||||
let bar_h = 18i32;
|
let bar_h = 28i32;
|
||||||
let y_top = screen_h as i32 - bar_h;
|
let y_top = screen_h as i32 - bar_h;
|
||||||
let y_row1 = y_top + 1;
|
let y_row1 = y_top + 2;
|
||||||
let y_row2 = y_top + 7;
|
let y_row2 = y_top + 12;
|
||||||
let y_row3 = y_top + 13;
|
let y_row3 = y_top + 22;
|
||||||
|
|
||||||
for row in y_top..screen_h as i32 {
|
for row in y_top..screen_h as i32 {
|
||||||
for x in 0..screen_w {
|
for x in 0..screen_w {
|
||||||
|
|||||||
+8
-5
@@ -51,9 +51,11 @@ fn depth_shown_in_hud() {
|
|||||||
let s = setup();
|
let s = setup();
|
||||||
let player = s.game.entities.all()[0].clone();
|
let player = s.game.entities.all()[0].clone();
|
||||||
let mut ui = verbatim::ui::UiLayer::new();
|
let mut ui = verbatim::ui::UiLayer::new();
|
||||||
|
let screen_w = 320;
|
||||||
|
let screen_h = 100;
|
||||||
ui.draw_hud(
|
ui.draw_hud(
|
||||||
80,
|
screen_w,
|
||||||
25,
|
screen_h,
|
||||||
Some(&player),
|
Some(&player),
|
||||||
s.game.tick,
|
s.game.tick,
|
||||||
verbatim::world::cell::MaterialId::Sand,
|
verbatim::world::cell::MaterialId::Sand,
|
||||||
@@ -68,10 +70,11 @@ fn depth_shown_in_hud() {
|
|||||||
player.level, player.xp, 0, 0, s.game.depth, s.game.tick
|
player.level, player.xp, 0, 0, s.game.depth, s.game.tick
|
||||||
);
|
);
|
||||||
let stats_w = verbatim::ui::UiLayer::text_width(&stats);
|
let stats_w = verbatim::ui::UiLayer::text_width(&stats);
|
||||||
let stats_x = (80 - stats_w).max(0);
|
let stats_x = (screen_w as i32 - stats_w as i32).max(0);
|
||||||
let line: String = (stats_x..80)
|
let y_row3 = screen_h as i32 - 28 + 22;
|
||||||
|
let line: String = (stats_x as i32..screen_w as i32)
|
||||||
.step_by(3)
|
.step_by(3)
|
||||||
.map(|x| ui.get(x, 24).map(|c| c.ch).unwrap_or(' '))
|
.map(|x| ui.get(x, y_row3).map(|c| c.ch).unwrap_or(' '))
|
||||||
.collect();
|
.collect();
|
||||||
assert!(line.contains("D:1"), "HUD should show depth: {}", line);
|
assert!(line.contains("D:1"), "HUD should show depth: {}", line);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user