feat(viz): enter a specific seed (S to type, Enter to apply)
Press S to begin seed entry, type digits (HUD shows the buffer), Enter applies and regenerates, Esc cancels, Backspace edits. Reroll still increments. Digit-only input; buffer capped under u64's range. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ab195306a5
commit
c13fc18d8f
1 changed files with 66 additions and 14 deletions
|
|
@ -201,7 +201,10 @@ fn draw_edges(snapshot: &Snapshot, layout: &Layout) {
|
|||
}
|
||||
|
||||
/// Draws the on-screen HUD: seed, current stage, and the controls hint.
|
||||
fn draw_hud(dungeon: &Dungeon) {
|
||||
///
|
||||
/// When `seed_input` is `Some`, the user is typing a seed: the top line becomes
|
||||
/// an entry prompt showing the buffer, and the hint switches to the entry keys.
|
||||
fn draw_hud(dungeon: &Dungeon, seed_input: Option<&str>) {
|
||||
let stage_count = dungeon.snapshots.len();
|
||||
let stage_label = dungeon
|
||||
.current()
|
||||
|
|
@ -209,7 +212,17 @@ fn draw_hud(dungeon: &Dungeon) {
|
|||
.unwrap_or("(empty)");
|
||||
let is_final = dungeon.stage + 1 == stage_count;
|
||||
|
||||
let seed_line = format!("seed: {}", dungeon.seed);
|
||||
// The top line doubles as the seed-entry prompt while typing.
|
||||
let (top_line, hint) = match seed_input {
|
||||
Some(buf) => (
|
||||
format!("set seed: {buf}_"),
|
||||
"Enter: apply Esc: cancel (digits only)",
|
||||
),
|
||||
None => (
|
||||
format!("seed: {}", dungeon.seed),
|
||||
"Space: reroll Left/Right: scrub stages S: set seed",
|
||||
),
|
||||
};
|
||||
let stage_line = format!(
|
||||
"stage {}/{}: {}{}",
|
||||
dungeon.stage + 1,
|
||||
|
|
@ -217,11 +230,11 @@ fn draw_hud(dungeon: &Dungeon) {
|
|||
stage_label,
|
||||
if is_final { " (final)" } else { "" },
|
||||
);
|
||||
let hint = "Space: reroll Left/Right: scrub stages";
|
||||
|
||||
// A dark plate behind the text so it stays readable over light floor tiles.
|
||||
draw_rectangle(0.0, 0.0, screen_width(), 64.0, Color::new(0.0, 0.0, 0.0, 0.55));
|
||||
draw_text(&seed_line, 12.0, 22.0, 24.0, WHITE);
|
||||
let top_color = if seed_input.is_some() { GOLD } else { WHITE };
|
||||
draw_text(&top_line, 12.0, 22.0, 24.0, top_color);
|
||||
draw_text(&stage_line, 12.0, 44.0, 22.0, SKYBLUE);
|
||||
draw_text(hint, 12.0, 60.0, 18.0, LIGHTGRAY);
|
||||
}
|
||||
|
|
@ -234,9 +247,13 @@ async fn main() {
|
|||
// determinism is unaffected — same seed always rebuilds the same dungeon.
|
||||
let mut seed: u64 = 0;
|
||||
let mut dungeon = Dungeon::generate(seed);
|
||||
// `Some(buffer)` while the user is typing a seed; `None` in normal mode.
|
||||
let mut seed_input: Option<String> = None;
|
||||
|
||||
loop {
|
||||
// --- input ---
|
||||
if seed_input.is_none() {
|
||||
// Normal mode: reroll, scrub, or begin seed entry.
|
||||
if is_key_pressed(KeyCode::Space) {
|
||||
seed = seed.wrapping_add(1);
|
||||
dungeon = Dungeon::generate(seed);
|
||||
|
|
@ -247,6 +264,41 @@ async fn main() {
|
|||
if is_key_pressed(KeyCode::Right) {
|
||||
dungeon.scrub(1);
|
||||
}
|
||||
if is_key_pressed(KeyCode::S) {
|
||||
// Begin seed entry; digits are collected on the following frames.
|
||||
seed_input = Some(String::new());
|
||||
}
|
||||
} else {
|
||||
// Seed-entry mode: collect digits, apply on Enter, cancel on Esc.
|
||||
let mut exit = false;
|
||||
{
|
||||
let buf = seed_input.as_mut().expect("in seed-entry mode");
|
||||
// Drain this frame's typed chars; keep digits only (so the `S`
|
||||
// that opened the mode and any other keys are ignored). Cap the
|
||||
// length well under u64's 20 digits so it always parses.
|
||||
while let Some(c) = get_char_pressed() {
|
||||
if c.is_ascii_digit() && buf.len() < 19 {
|
||||
buf.push(c);
|
||||
}
|
||||
}
|
||||
if is_key_pressed(KeyCode::Backspace) {
|
||||
buf.pop();
|
||||
}
|
||||
if is_key_pressed(KeyCode::Enter) {
|
||||
// Empty or unparseable buffer simply cancels (no change).
|
||||
if let Ok(parsed) = buf.parse::<u64>() {
|
||||
seed = parsed;
|
||||
dungeon = Dungeon::generate(seed);
|
||||
}
|
||||
exit = true;
|
||||
} else if is_key_pressed(KeyCode::Escape) {
|
||||
exit = true;
|
||||
}
|
||||
}
|
||||
if exit {
|
||||
seed_input = None;
|
||||
}
|
||||
}
|
||||
|
||||
// --- draw ---
|
||||
clear_background(Color::new(0.04, 0.04, 0.05, 1.0));
|
||||
|
|
@ -271,7 +323,7 @@ async fn main() {
|
|||
);
|
||||
}
|
||||
|
||||
draw_hud(&dungeon);
|
||||
draw_hud(&dungeon, seed_input.as_deref());
|
||||
|
||||
next_frame().await;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue