HUD Anchors¶
a game HUD pinned to screen corners that follows the window.
▶ Run in browserTags: ui hud anchors layout responsive
A heads-up display is placed by anchors, never by coordinates. Each top-level
Control names the edge or corner it belongs to with anchor= and how far in
from that edge it sits with inset=, and the engine keeps it there whatever
size the window becomes:
ProgressBar(anchor=Anchor.TOP_LEFT, inset=16, size=(220, 22))
Label("Score: 0", anchor=Anchor.TOP_RIGHT, inset=16)
Label("...", anchor=Anchor.CENTER_BOTTOM, inset=12)
The health bar is a ProgressBar hugging the top-left corner: setting its
value resizes the fill and updates the percentage it draws, and its
fill_colour steps from green through amber to red as health falls. The score
in the top-right corner is a content-sized Label, so it re-fits as the number
grows while its right edge stays 16 pixels from the window edge. The hint is
centred along the bottom. Resize the window and every piece keeps its gutter.
Health is one Axis1D action, Up heals and Down hurts, read with
Input.value("health"). With the mouse or a finger, hold on the health bar to
heal it and anywhere else to hurt it.
Source¶
1# /// simvx
2# tags = ["ui", "hud", "anchors", "layout", "responsive"]
3# web = { width = 800, height = 600, responsive = true }
4# ///
5"""HUD Anchors: a game HUD pinned to screen corners that follows the window.
6
7A heads-up display is placed by anchors, never by coordinates. Each top-level
8`Control` names the edge or corner it belongs to with `anchor=` and how far in
9from that edge it sits with `inset=`, and the engine keeps it there whatever
10size the window becomes:
11
12 ProgressBar(anchor=Anchor.TOP_LEFT, inset=16, size=(220, 22))
13 Label("Score: 0", anchor=Anchor.TOP_RIGHT, inset=16)
14 Label("...", anchor=Anchor.CENTER_BOTTOM, inset=12)
15
16The health bar is a `ProgressBar` hugging the top-left corner: setting its
17`value` resizes the fill and updates the percentage it draws, and its
18`fill_colour` steps from green through amber to red as health falls. The score
19in the top-right corner is a content-sized `Label`, so it re-fits as the number
20grows while its right edge stays 16 pixels from the window edge. The hint is
21centred along the bottom. Resize the window and every piece keeps its gutter.
22
23Health is one `Axis1D` action, Up heals and Down hurts, read with
24`Input.value("health")`. With the mouse or a finger, hold on the health bar to
25heal it and anywhere else to hurt it.
26"""
27
28from simvx.core import Anchor, Axis1D, Colour, Input, Key, Label, Node, Pointer, ProgressBar
29from simvx.graphics import App
30
31HEAL_RATE = 60.0 # health points per second while healing or hurting
32
33
34class HudAnchorsDemo(Node):
35 input_context = {"health": [Axis1D(low=Key.DOWN, high=Key.UP)], "press": [Pointer.PRIMARY]}
36
37 def on_ready(self):
38 self.score = 0
39 self.health_bar = self.add_child(
40 ProgressBar(name="HealthBar", anchor=Anchor.TOP_LEFT, inset=16, size=(220, 22), value=75.0)
41 )
42 self.score_label = self.add_child(
43 Label("Score: 0", name="Score", anchor=Anchor.TOP_RIGHT, inset=16, font_size=16.0)
44 )
45 self.score_label.text_colour = Colour.hex("#FFD166")
46 hint = self.add_child(
47 Label(
48 "Up / Down, or hold the bar to heal and elsewhere to hurt",
49 name="Hint",
50 anchor=Anchor.CENTER_BOTTOM,
51 inset=12,
52 font_size=13.0,
53 )
54 )
55 hint.text_colour = Colour.LIGHT_GRAY
56
57 def on_update(self, dt: float):
58 direction = Input.value("health")
59 if Input.pressed("press"):
60 direction = 1.0 if self.health_bar.is_point_inside(Input.mouse_position) else -1.0
61
62 bar = self.health_bar
63 bar.value = min(max(bar.value + direction * HEAL_RATE * dt, bar.min_value), bar.max_value)
64 if bar.percentage < 0.3:
65 bar.fill_colour = Colour.hex("#E63946")
66 elif bar.percentage < 0.6:
67 bar.fill_colour = Colour.hex("#F4A261")
68 else:
69 bar.fill_colour = Colour.hex("#43C463")
70
71 self.score += 1
72 self.score_label.text = f"Score: {self.score}"
73
74
75if __name__ == "__main__":
76 App(title="SimVX HUD Anchors", width=800, height=600).run(HudAnchorsDemo())