feat(*): Redesign HUD scoreboard as a single timer/score/team banner

This commit is contained in:
Josh Creek
2026-07-28 19:24:40 +01:00
parent 93f90ca6de
commit a9b7b450d5
2 changed files with 87 additions and 40 deletions
+31 -9
View File
@@ -5,10 +5,12 @@
extends CanvasLayer
class_name HUDController
@onready var timer_label = get_node("Control/TimerLabel")
@onready var score_row = get_node_or_null("Control/ScoreRow")
@onready var team0_score_label = get_node_or_null("Control/ScoreRow/Team0Score")
@onready var team1_score_label = get_node_or_null("Control/ScoreRow/Team1Score")
@onready var score_row = get_node_or_null("Control/ScoreboardPanel")
@onready var timer_label = get_node_or_null("Control/ScoreboardPanel/ScoreRow/TimerLabel")
@onready var team0_name_label = get_node_or_null("Control/ScoreboardPanel/ScoreRow/Team0Name")
@onready var team0_score_label = get_node_or_null("Control/ScoreboardPanel/ScoreRow/Team0Score")
@onready var team1_score_label = get_node_or_null("Control/ScoreboardPanel/ScoreRow/Team1Score")
@onready var team1_name_label = get_node_or_null("Control/ScoreboardPanel/ScoreRow/Team1Name")
@onready var kickoff_label = get_node_or_null("Control/KickoffLabel")
@onready var result_overlay = get_node_or_null("Control/ResultOverlay")
@onready var result_label = get_node_or_null("Control/ResultOverlay/Center/VBox/ResultLabel")
@@ -26,6 +28,7 @@ const TEAM_NAMES := {0: "Blue", 1: "Orange"}
const TEAM_COLORS := {0: Color(0.25, 0.55, 1.0), 1: Color(1.0, 0.5, 0.15)}
var ship: Node
var _last_score := {0: 0, 1: 0}
func _ready():
# Wait one frame to ensure ship is ready and added to group
@@ -67,8 +70,14 @@ func _initialize_hud():
var has_score = game_manager and game_manager.has_signal("score_changed")
if has_score:
game_manager.score_changed.connect(_on_score_changed)
for label in [team0_name_label, team0_score_label, team1_score_label, team1_name_label]:
if label and is_instance_valid(label):
label.visible = has_score
# The banner itself (timer + score share one panel) only fully hides
# when neither signal exists at all.
if score_row and is_instance_valid(score_row):
score_row.visible = has_score
score_row.visible = has_timer or has_score
if game_manager and game_manager.has_signal("match_ended"):
game_manager.match_ended.connect(_on_match_ended)
@@ -126,10 +135,23 @@ func update_timer(time_text: String):
timer_label.text = time_text
func _on_score_changed(score: Dictionary):
if team0_score_label and is_instance_valid(team0_score_label):
team0_score_label.text = str(score.get(0, 0))
if team1_score_label and is_instance_valid(team1_score_label):
team1_score_label.text = str(score.get(1, 0))
_update_score_label(team0_score_label, score, 0)
_update_score_label(team1_score_label, score, 1)
_last_score = score.duplicate()
func _update_score_label(label: Label, score: Dictionary, team: int):
if not label or not is_instance_valid(label):
return
label.text = str(score.get(team, 0))
if score.get(team, 0) > _last_score.get(team, 0):
_flash_score_label(label)
# Brief scale pop to draw the eye to whichever team just scored.
func _flash_score_label(label: Label) -> void:
label.pivot_offset = label.size / 2.0
var tween := create_tween()
tween.tween_property(label, "scale", Vector2(1.4, 1.4), 0.1)
tween.tween_property(label, "scale", Vector2(1.0, 1.0), 0.2)
func _on_kickoff_countdown(count: int):
if not kickoff_label or not is_instance_valid(kickoff_label):