132 lines
4.6 KiB
GDScript
132 lines
4.6 KiB
GDScript
class_name JuggleBoardHud
|
|
extends CanvasLayer
|
|
## HUD P2B: bersaglio e cartigli sul pannello laterale illustrato.
|
|
|
|
signal options_requested
|
|
signal back_requested
|
|
|
|
const DISPLAY_FONT := preload("res://shared/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf")
|
|
const TARGET_SCRIPT := preload("res://games/juggleboard/scripts/components/target_dot.gd")
|
|
const HEARTS_SCRIPT := preload("res://games/juggleboard/scripts/ui/hearts_display.gd")
|
|
const BACK_BUTTON_ART := preload("res://menus/assets/common/pulsante_indietro.png")
|
|
|
|
var target_dot: Node2D
|
|
var score_label: Label
|
|
var combo_label: Label
|
|
var help_label: Label
|
|
var milestone_label: Label
|
|
var flash: ColorRect
|
|
var hearts: Node2D
|
|
var back_button: TextureButton
|
|
|
|
|
|
func _ready() -> void:
|
|
_build()
|
|
|
|
|
|
func _build() -> void:
|
|
var ink := Color("#251b17")
|
|
var x_scale := JuggleBoardConfig.horizontal_scale(get_viewport().get_visible_rect().size.x)
|
|
|
|
# Node2D ha pivot locale (0, 0); target_dot disegna l'asset simmetricamente
|
|
# intorno a quel pivot, quindi si usa il centro misurato della cornice P2B.
|
|
target_dot = TARGET_SCRIPT.new()
|
|
target_dot.position = Vector2(JuggleBoardConfig.TARGET_CENTER.x * x_scale, JuggleBoardConfig.TARGET_CENTER.y)
|
|
add_child(target_dot)
|
|
|
|
back_button = _make_back_button()
|
|
add_child(back_button)
|
|
MenuUI.set_normalized_rect(back_button, MenuUI.BACK_BUTTON_CENTER, MenuUI.BACK_BUTTON_SIZE)
|
|
|
|
score_label = _make_label("", Vector2(112 * x_scale, 520), Vector2(220 * x_scale, 45), 25, ink)
|
|
score_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
score_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
combo_label = _make_label("", Vector2(112 * x_scale, 606), Vector2(220 * x_scale, 45), 24, ink)
|
|
combo_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
combo_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
|
|
hearts = HEARTS_SCRIPT.new()
|
|
hearts.position = Vector2(84 * x_scale, 655)
|
|
hearts.visible = false
|
|
add_child(hearts)
|
|
|
|
# Le opzioni restano accessibili da Esc per non introdurre elementi estranei
|
|
# al mockup P2B; il lock adulto e la persistenza delle impostazioni non cambiano.
|
|
help_label = _make_label("", Vector2.ZERO, Vector2.ZERO, 1, ink)
|
|
help_label.visible = false
|
|
|
|
milestone_label = _make_label("", Vector2(350 * x_scale, 20), Vector2(820 * x_scale, 80), 46, Color("#9e5420"))
|
|
milestone_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
milestone_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
milestone_label.visible = false
|
|
|
|
flash = ColorRect.new()
|
|
flash.color = Color(1, 0.95, 0.72)
|
|
flash.position = Vector2.ZERO
|
|
flash.size = get_viewport().get_visible_rect().size
|
|
flash.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
flash.modulate.a = 0.0
|
|
flash.visible = false
|
|
add_child(flash)
|
|
|
|
|
|
func _make_back_button() -> TextureButton:
|
|
var button := TextureButton.new()
|
|
button.texture_normal = BACK_BUTTON_ART
|
|
button.texture_hover = BACK_BUTTON_ART
|
|
button.texture_pressed = BACK_BUTTON_ART
|
|
button.ignore_texture_size = true
|
|
button.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT_CENTERED
|
|
button.tooltip_text = "Torna al menu Juggle"
|
|
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
button.mouse_entered.connect(func(): button.modulate = Color(1.10, 1.10, 1.10, 1.0))
|
|
button.mouse_exited.connect(func(): button.modulate = Color.WHITE)
|
|
button.pressed.connect(func(): back_requested.emit())
|
|
return button
|
|
|
|
|
|
func reset(score: int, combo: float, lives: int, survival: bool) -> void:
|
|
set_score(score, combo)
|
|
hearts.set_lives(lives)
|
|
hearts.visible = survival
|
|
|
|
|
|
func set_score(score: int, combo: float) -> void:
|
|
score_label.text = "punteggio %03d" % score
|
|
combo_label.text = "livello %d" % (1 + int(score / 1000))
|
|
|
|
|
|
func set_target(color: Color, shown: bool = true) -> void:
|
|
if shown:
|
|
target_dot.set_color(color)
|
|
target_dot.visible = shown
|
|
|
|
|
|
func celebrate(amount: int) -> void:
|
|
milestone_label.text = "%d PUNTI!" % amount
|
|
milestone_label.visible = true
|
|
milestone_label.modulate.a = 1.0
|
|
flash.visible = true
|
|
flash.modulate.a = 0.16
|
|
var tween := create_tween()
|
|
tween.set_parallel(true)
|
|
tween.tween_property(milestone_label, "modulate:a", 0.0, 0.8).set_delay(0.6)
|
|
tween.tween_property(flash, "modulate:a", 0.0, 0.4)
|
|
tween.chain().tween_callback(func():
|
|
milestone_label.visible = false
|
|
flash.visible = false
|
|
)
|
|
|
|
|
|
func _make_label(text: String, position: Vector2, size: Vector2, font_size: int, color: Color) -> Label:
|
|
var label := Label.new()
|
|
label.text = text
|
|
label.position = position
|
|
label.size = size
|
|
label.add_theme_font_override("font", DISPLAY_FONT)
|
|
label.add_theme_font_size_override("font_size", font_size)
|
|
label.add_theme_color_override("font_color", color)
|
|
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(label)
|
|
return label
|