New screens, new hud, new intro menu, some UI element changes

This commit is contained in:
2026-07-30 13:52:39 +03:00
parent bf7a454ad0
commit ff75dacfb6
87 changed files with 209 additions and 1665 deletions
+64 -53
View File
@@ -1,22 +1,28 @@
extends CanvasLayer
const _GOLD := Color(1.00, 0.78, 0.22)
const _CREAM := Color(0.88, 0.83, 0.72)
const _MUTED := Color(0.65, 0.60, 0.48)
const _BG := Color(0.06, 0.04, 0.02, 0.78)
const _BADGE := Color(0.16, 0.10, 0.03, 0.90)
const _BORDER := Color(0.65, 0.48, 0.15, 0.55)
const _GOLD := Color(1.00, 0.78, 0.22)
const _CREAM := Color(0.93, 0.88, 0.72)
const _MUTED := Color(0.66, 0.60, 0.46)
# Per-ability trim colour, tying each tile (and its key cap) to that ability's FX.
# Order matches _ABILITY_ICONS: kick, slam, dash, roll.
const _ABILITY_ACCENT: Array[Color] = [
Color(1.00, 0.62, 0.16), # Kick — ember orange
Color(0.98, 0.34, 0.20), # Slam — crimson
Color(0.45, 0.75, 1.00), # Dash — sky blue
Color(1.00, 0.82, 0.32), # Roll — gold
]
const _ABILITY_ICONS: Array[String] = [
"res://HUD/HUD_0000_ability_JALG.png",
"res://HUD/HUD_0001_ability_SLAM.png",
"res://HUD/HUD_0002_ability_DASH.png",
"res://HUD/HUD_0003_ability_ROLL.png",
"res://HUD/KICK.png",
"res://HUD/SLAM.png",
"res://HUD/DASH.png",
"res://HUD/ROLL.png",
]
const _ABILITY_ACTIONS: Array[StringName] = [
&"ability_kick", &"ability_slam", &"ability_dash", &"ability_roll",
]
# Fallback label shown in a slot whose icon file doesn't exist yet (e.g. ROLL).
# Fallback label shown in a slot whose icon file fails to load.
const _ABILITY_NAMES: Array[String] = ["Kick", "Slam", "Dash", "Roll"]
var _controls_visible: bool = false
@@ -28,6 +34,8 @@ var _player: Node = null
var _died_connected: bool = false
var _cd_overlays: Array[ColorRect] = []
var _cd_labels: Array[Label] = []
var _ability_bar: HBoxContainer
var _ability_panels: Array[PanelContainer] = []
# Win/lose screen. _game_over latches so the result is shown once; _result_win
# records which way it went (read by the gameplay test).
@@ -201,37 +209,36 @@ func _build_game_over() -> void:
row.add_child(menu)
# A bordered, rounded, gold-trimmed panel background — the HUD's one repeated look.
# Margins are symmetric (L=R, T=B); pass a transparent border to draw none.
func _panel_style(bg: Color, corner: int, h_margin: float, v_margin: float,
border: Color = _BORDER) -> StyleBoxFlat:
var s := StyleBoxFlat.new()
s.bg_color = bg
s.set_corner_radius_all(corner)
if border.a > 0.0:
s.set_border_width_all(1)
s.border_color = border
s.content_margin_left = h_margin
s.content_margin_right = h_margin
s.content_margin_top = v_margin
s.content_margin_bottom = v_margin
return s
const _SLOT_SEPARATION: int = 10
func _build_ability_bar() -> void:
var bar := HBoxContainer.new()
bar.add_theme_constant_override("separation", 10)
bar.anchor_left = 0.5
bar.anchor_right = 0.5
bar.anchor_top = 1.0
bar.anchor_bottom = 1.0
bar.grow_horizontal = Control.GROW_DIRECTION_BOTH
bar.grow_vertical = Control.GROW_DIRECTION_BEGIN
bar.offset_left = -160.0
bar.offset_bottom = -20.0
add_child(bar)
_ability_bar = HBoxContainer.new()
_ability_bar.add_theme_constant_override("separation", _SLOT_SEPARATION)
_ability_bar.anchor_left = 0.5
_ability_bar.anchor_right = 0.5
_ability_bar.anchor_top = 1.0
_ability_bar.anchor_bottom = 1.0
_ability_bar.grow_horizontal = Control.GROW_DIRECTION_BOTH
_ability_bar.grow_vertical = Control.GROW_DIRECTION_BEGIN
_ability_bar.offset_bottom = -20.0
add_child(_ability_bar)
for i: int in 4:
bar.add_child(_build_ability_slot(i))
_ability_bar.add_child(_build_ability_slot(i))
_layout_ability_bar()
get_viewport().size_changed.connect(_layout_ability_bar)
# Size the ability slots as a fraction of the viewport (clamped) so the bar scales
# with the window, and keep it horizontally centred by matching the HBox offsets.
func _layout_ability_bar() -> void:
var vp := get_viewport().get_visible_rect().size
var slot := clampf(minf(vp.x * 0.055, vp.y * 0.11), 56.0, 104.0)
for panel: PanelContainer in _ability_panels:
panel.custom_minimum_size = Vector2(slot, slot)
var total := slot * 4.0 + float(_SLOT_SEPARATION) * 3.0
_ability_bar.offset_left = -total * 0.5
_ability_bar.offset_right = total * 0.5
func _build_ability_slot(idx: int) -> Control:
@@ -240,8 +247,10 @@ func _build_ability_slot(idx: int) -> Control:
var panel := PanelContainer.new()
panel.custom_minimum_size = Vector2(72.0, 72.0)
panel.add_theme_stylebox_override("panel", _panel_style(_BG, 6, 4.0, 4.0))
panel.add_theme_stylebox_override(
"panel", UiTheme.plaque(UiTheme.LEATHER, _ABILITY_ACCENT[idx], 4, 5.0, 5.0))
vbox.add_child(panel)
_ability_panels.append(panel)
var stack := Control.new()
stack.set_anchors_preset(Control.PRESET_FULL_RECT)
@@ -250,8 +259,12 @@ func _build_ability_slot(idx: int) -> Control:
if ResourceLoader.exists(_ABILITY_ICONS[idx]):
var icon := TextureRect.new()
icon.texture = load(_ABILITY_ICONS[idx])
# Ignore the texture's native size so a large source PNG doesn't blow the
# slot's minimum size out; scale-to-fit the box while keeping aspect.
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.set_anchors_preset(Control.PRESET_FULL_RECT)
icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
stack.add_child(icon)
else:
var name_lbl := Label.new()
@@ -288,8 +301,11 @@ func _build_ability_slot(idx: int) -> Control:
var key_lbl := Label.new()
key_lbl.text = Controls.get_key_label(_ABILITY_ACTIONS[idx])
key_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
key_lbl.add_theme_color_override("font_color", _GOLD)
key_lbl.add_theme_font_size_override("font_size", 12)
key_lbl.add_theme_font_override("font", UiFonts.body())
key_lbl.add_theme_color_override("font_color", _ABILITY_ACCENT[idx].lerp(_CREAM, 0.35))
key_lbl.add_theme_color_override("font_outline_color", Color(0, 0, 0, 0.85))
key_lbl.add_theme_constant_override("outline_size", 3)
key_lbl.add_theme_font_size_override("font_size", 13)
vbox.add_child(key_lbl)
return vbox
@@ -312,7 +328,8 @@ func _build_tab_hint() -> void:
func _build_controls_panel() -> void:
_controls_panel = PanelContainer.new()
_controls_panel.add_theme_stylebox_override("panel", _panel_style(_BG, 7, 14.0, 10.0))
_controls_panel.add_theme_stylebox_override(
"panel", UiTheme.plaque(UiTheme.LEATHER, UiTheme.BORDER, 4, 16.0, 12.0))
_controls_panel.anchor_left = 0.0
_controls_panel.anchor_top = 1.0
@@ -334,9 +351,7 @@ func _build_controls_panel() -> void:
Controls.get_key_label(&"move_back"),
Controls.get_key_label(&"move_right"),
]
_row(vbox, move_keys, "Move (not intended)", _MUTED)
_row(vbox, "LMB (hold)", "Right horn", _CREAM)
_row(vbox, "RMB (hold)", "Left horn", _CREAM)
_row(vbox, move_keys, "Move", _CREAM)
_row(vbox, Controls.get_key_label(&"ability_kick"), "Kick", _CREAM)
_row(vbox, Controls.get_key_label(&"ability_slam"), "Slam", _CREAM)
_row(vbox, Controls.get_key_label(&"ability_dash"), "Dash", _CREAM)
@@ -346,11 +361,7 @@ func _build_controls_panel() -> void:
_row(vbox, "Esc", "Back to menu", _MUTED)
var sep := HSeparator.new()
var sep_style := StyleBoxFlat.new()
sep_style.bg_color = Color(0.65, 0.48, 0.15, 0.30)
sep_style.content_margin_top = 4.0
sep_style.content_margin_bottom = 4.0
sep.add_theme_stylebox_override("separator", sep_style)
sep.add_theme_stylebox_override("separator", UiTheme.rule())
vbox.add_child(sep)
_toggle_btn = _make_button("Show controls")
@@ -363,8 +374,8 @@ func _make_button(label_text: String) -> Button:
btn.text = label_text
btn.process_mode = Node.PROCESS_MODE_ALWAYS
var normal := _panel_style(Color(0.18, 0.12, 0.04, 0.90), 5, 16.0, 8.0)
var hover := _panel_style(Color(0.30, 0.20, 0.06, 0.95), 5, 16.0, 8.0, _GOLD)
var normal := UiTheme.plaque(Color(0.10, 0.07, 0.03, 0.90), _GOLD, 3, 18.0, 9.0)
var hover := UiTheme.plaque(Color(0.16, 0.10, 0.04, 0.96), _CREAM, 3, 18.0, 9.0)
btn.add_theme_stylebox_override("normal", normal)
btn.add_theme_stylebox_override("hover", hover)
@@ -384,7 +395,7 @@ func _row(parent: VBoxContainer, key: String, desc: String, desc_color: Color) -
parent.add_child(row)
var badge := PanelContainer.new()
badge.add_theme_stylebox_override("panel", _panel_style(_BADGE, 3, 6.0, 2.0, Color(0, 0, 0, 0)))
badge.add_theme_stylebox_override("panel", UiTheme.badge())
badge.custom_minimum_size = Vector2(100.0, 0.0)
row.add_child(badge)