nodes/hud.pyΒΆ
Part of GDQuest Open RPG.
1"""Front-of-game title card plus the persistent bottom controls strip."""
2
3from __future__ import annotations
4
5from simvx.core import Node2D
6from simvx.core.input.state import Input
7from simvx.core.signals import Signal
8
9from .settings import PANEL_BORDER, PANEL_BORDER_FOCUS, TEXT, TEXT_DIM
10
11TITLE_LINE = "OPEN RPG"
12SUBTITLE_LINE = "a SimVX port of GDQuest's godot-open-rpg"
13
14HOW_TO = [
15 "WASD, arrows, D-pad or the on-screen pad walk one tile at a time",
16 "Tap a tile walk there along a BFS path",
17 "E, (A) or the pad's button talk to whoever you are facing",
18 "Red tiles wild encounters, yellow shrine saves",
19 "Q or (Back) quit",
20]
21
22
23class TitleScreen(Node2D):
24 """Full-viewport title card. Emits ``started`` on confirm or click."""
25
26 def __init__(self) -> None:
27 super().__init__()
28 self.z_index = 9000
29 self.started = Signal()
30
31 def on_update(self, dt: float) -> None:
32 if Input.just_pressed("advance"):
33 self.started.emit()
34 self.destroy()
35
36 def on_draw(self, renderer) -> None:
37 w, h = self.viewport_size
38 renderer.rect((0, 0), (w, h), fill=(0.05, 0.06, 0.10, 0.94))
39
40 cx = w * 0.5
41 title_y = h * 0.16
42 renderer.text(
43 TITLE_LINE, (cx - renderer.text_width(TITLE_LINE, 4.0) * 0.5, title_y), fill=PANEL_BORDER_FOCUS, scale=4.0
44 )
45 renderer.text(
46 SUBTITLE_LINE, (cx - renderer.text_width(SUBTITLE_LINE, 1.2) * 0.5, title_y + 60), fill=TEXT_DIM, scale=1.2
47 )
48
49 # How-to block: left-aligned as one column so the key names line up.
50 block_w = max(renderer.text_width(line, 1.2) for line in HOW_TO)
51 x = cx - block_w * 0.5
52 y = h * 0.40
53 for line in HOW_TO:
54 renderer.text(line, (x, y), fill=TEXT, scale=1.2)
55 y += 30
56
57 prompt = "ENTER, SPACE, (A) or tap to begin"
58 renderer.text(
59 prompt, (cx - renderer.text_width(prompt, 1.6) * 0.5, h - 110), fill=PANEL_BORDER_FOCUS, scale=1.6
60 )
61
62
63class ControlsStrip(Node2D):
64 """Thin bar pinned to the bottom of the viewport listing the live controls."""
65
66 BAR_HEIGHT = 26
67
68 def __init__(self) -> None:
69 super().__init__()
70 self.z_index = 4000
71 self._hint = ""
72
73 @property
74 def hint(self) -> str:
75 """Control legend currently shown. Assigning a new one re-draws the bar."""
76 return self._hint
77
78 @hint.setter
79 def hint(self, value: str) -> None:
80 if value != self._hint:
81 self._hint = value
82 self.queue_redraw()
83
84 def on_draw(self, renderer) -> None:
85 if not self._hint:
86 return
87 w, h = self.viewport_size
88 y = h - self.BAR_HEIGHT
89 renderer.rect((0, y), (w, self.BAR_HEIGHT), fill=(0.06, 0.07, 0.11, 0.88))
90 renderer.rect((0, y), (w, 1), fill=PANEL_BORDER)
91 renderer.text(self._hint, (14, y + 7), fill=TEXT_DIM, scale=1.0)