feat: trigger tent animations and piedone transition on click selection
This commit is contained in:
@@ -17,6 +17,28 @@ const BACK_BUTTON := preload("res://menus/assets/common/pulsante_indietro.png")
|
|||||||
const SETTINGS_BUTTON := preload("res://menus/assets/common/pulsante_rotellina.png")
|
const SETTINGS_BUTTON := preload("res://menus/assets/common/pulsante_rotellina.png")
|
||||||
const CIRCUS_SIGN_PANEL := preload("res://menus/assets/p1/upendi_circus_sign_panel.png")
|
const CIRCUS_SIGN_PANEL := preload("res://menus/assets/p1/upendi_circus_sign_panel.png")
|
||||||
const CIRCUS_SIGN_ROPES := preload("res://menus/assets/p1/upendi_circus_sign_ropes.png")
|
const CIRCUS_SIGN_ROPES := preload("res://menus/assets/p1/upendi_circus_sign_ropes.png")
|
||||||
|
const PLAY_BUTTON := preload("res://menus/assets/common/pulsante_gioca.png")
|
||||||
|
|
||||||
|
var piedone: Control
|
||||||
|
var piedone_title: Label
|
||||||
|
var piedone_desc: Label
|
||||||
|
var piedone_play: TextureButton
|
||||||
|
var selected_tent: String = "" # "juggle" o "gym"
|
||||||
|
var piedone_tween: Tween
|
||||||
|
var blue_tent_control: Control
|
||||||
|
var red_tent_control: Control
|
||||||
|
|
||||||
|
# Riferimenti alle animazioni e shader per ciascun tendone
|
||||||
|
var blue_mat: ShaderMaterial
|
||||||
|
var red_mat: ShaderMaterial
|
||||||
|
|
||||||
|
var blue_curtain_dir: Array = [0]
|
||||||
|
var blue_curtain_timer: Timer
|
||||||
|
var blue_lights: TextureRect
|
||||||
|
|
||||||
|
var red_curtain_dir: Array = [0]
|
||||||
|
var red_curtain_timer: Timer
|
||||||
|
var red_lights: TextureRect
|
||||||
|
|
||||||
const CURTAIN_FRAMES := [
|
const CURTAIN_FRAMES := [
|
||||||
preload("res://menus/assets/p1/curtain_anim/curtain_00.png"),
|
preload("res://menus/assets/p1/curtain_anim/curtain_00.png"),
|
||||||
@@ -48,11 +70,14 @@ func _build() -> void:
|
|||||||
MenuUI.add_full_texture(self, CLOUDS, MenuUI.ambient_material(1.0, 0.16))
|
MenuUI.add_full_texture(self, CLOUDS, MenuUI.ambient_material(1.0, 0.16))
|
||||||
_add_sign()
|
_add_sign()
|
||||||
|
|
||||||
# Solo il tendone blu di riferimento attiva lo shader delle lucine in hover.
|
# Costruzione dei due tendoni selezionabili al click (entrambi con luci e sipario)
|
||||||
var blue := _add_tent_button(BLUE_TENT, Vector2(0.29, 0.46), true)
|
var blue := _add_tent_button(BLUE_TENT, Vector2(0.29, 0.46), "juggle")
|
||||||
blue.pressed.connect(func(): juggle_requested.emit(blue))
|
blue_tent_control = blue
|
||||||
var red := _add_tent_button(RED_TENT, Vector2(0.71, 0.46), false)
|
blue.pressed.connect(func(): _select_tent("juggle"))
|
||||||
red.pressed.connect(func(): gym_requested.emit(red))
|
|
||||||
|
var red := _add_tent_button(RED_TENT, Vector2(0.71, 0.46), "gym")
|
||||||
|
red_tent_control = red
|
||||||
|
red.pressed.connect(func(): _select_tent("gym"))
|
||||||
|
|
||||||
_add_bottom_bar()
|
_add_bottom_bar()
|
||||||
MenuUI.add_image(self, SETTINGS_BUTTON, Vector2(0.91, 0.13), Vector2(0.09, 0.14))
|
MenuUI.add_image(self, SETTINGS_BUTTON, Vector2(0.91, 0.13), Vector2(0.09, 0.14))
|
||||||
@@ -61,36 +86,27 @@ func _build() -> void:
|
|||||||
exit_button.pressed.connect(func(): exit_requested.emit())
|
exit_button.pressed.connect(func(): exit_requested.emit())
|
||||||
|
|
||||||
|
|
||||||
func _add_tent_button(texture: Texture2D, center: Vector2, has_lights := false) -> TextureButton:
|
func _add_tent_button(texture: Texture2D, center: Vector2, tent_id: String) -> TextureButton:
|
||||||
var button := MenuUI.add_image_button(self, texture, center, Vector2(0.36, 0.59))
|
var button := MenuUI.add_image_button(self, texture, center, Vector2(0.36, 0.59))
|
||||||
var mat := MenuUI.tent_material(0.0) if has_lights else MenuUI.tent_star_material()
|
var mat := MenuUI.tent_material(0.0)
|
||||||
button.material = mat
|
button.material = mat
|
||||||
button.tooltip_text = "Apri questo percorso"
|
button.tooltip_text = "Seleziona questo percorso"
|
||||||
|
|
||||||
# Glow stella su entrambi i tendoni al passaggio del mouse
|
if tent_id == "juggle":
|
||||||
button.mouse_entered.connect(func():
|
blue_mat = mat
|
||||||
mat.set_shader_parameter("hover_strength", 1.0)
|
_setup_tent_interactive(button, center, "blue")
|
||||||
if has_lights:
|
elif tent_id == "gym":
|
||||||
mat.set_shader_parameter("garland_strength", 1.0)
|
red_mat = mat
|
||||||
)
|
_setup_tent_interactive(button, center, "red")
|
||||||
button.mouse_exited.connect(func():
|
|
||||||
mat.set_shader_parameter("hover_strength", 0.0)
|
|
||||||
if has_lights:
|
|
||||||
mat.set_shader_parameter("garland_strength", 0.0)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Animazione apertura sipario e lucine in hover
|
|
||||||
if has_lights:
|
|
||||||
_setup_hover_curtain_and_garland(button, center)
|
|
||||||
|
|
||||||
return button
|
return button
|
||||||
|
|
||||||
|
|
||||||
func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vector2) -> void:
|
func _setup_tent_interactive(parent_button: TextureButton, center: Vector2, color_id: String) -> void:
|
||||||
# Sipario: parte chiuso (frame 0). All'hover-in si apre (0 -> 6).
|
# Sipario: parte chiuso (frame 0). Alla selezione si apre (0 -> 6).
|
||||||
# All'hover-out si richiude al contrario (6 -> 0).
|
# Alla deselezione si richiude al contrario (6 -> 0).
|
||||||
var curtain := TextureRect.new()
|
var curtain := TextureRect.new()
|
||||||
curtain.name = "Curtain"
|
curtain.name = color_id.capitalize() + "Curtain"
|
||||||
curtain.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
curtain.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||||
curtain.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
curtain.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
curtain.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
curtain.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
@@ -98,11 +114,12 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect
|
|||||||
add_child(curtain)
|
add_child(curtain)
|
||||||
MenuUI.set_normalized_rect(curtain, center, Vector2(0.36, 0.59))
|
MenuUI.set_normalized_rect(curtain, center, Vector2(0.36, 0.59))
|
||||||
|
|
||||||
var curtain_idx := [0]
|
|
||||||
var curtain_dir := [0] # 0 = fermo, 1 = apre, -1 = chiude
|
var curtain_dir := [0] # 0 = fermo, 1 = apre, -1 = chiude
|
||||||
var curtain_timer := Timer.new()
|
var curtain_timer := Timer.new()
|
||||||
|
curtain_timer.name = color_id.capitalize() + "CurtainTimer"
|
||||||
curtain_timer.wait_time = 1.0 / 12.5
|
curtain_timer.wait_time = 1.0 / 12.5
|
||||||
curtain_timer.process_mode = Node.PROCESS_MODE_ALWAYS
|
curtain_timer.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||||
|
var curtain_idx := [0]
|
||||||
curtain_timer.timeout.connect(func():
|
curtain_timer.timeout.connect(func():
|
||||||
if curtain_dir[0] == 1:
|
if curtain_dir[0] == 1:
|
||||||
if curtain_idx[0] < CURTAIN_FRAMES.size() - 1:
|
if curtain_idx[0] < CURTAIN_FRAMES.size() - 1:
|
||||||
@@ -110,7 +127,7 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect
|
|||||||
curtain.texture = CURTAIN_FRAMES[curtain_idx[0]]
|
curtain.texture = CURTAIN_FRAMES[curtain_idx[0]]
|
||||||
curtain.visible = true
|
curtain.visible = true
|
||||||
else:
|
else:
|
||||||
# Completamente aperto: frame 06 è vuoto/trasparente
|
# Completamente aperto
|
||||||
curtain.texture = CURTAIN_FRAMES[curtain_idx[0]]
|
curtain.texture = CURTAIN_FRAMES[curtain_idx[0]]
|
||||||
curtain_dir[0] = 0
|
curtain_dir[0] = 0
|
||||||
curtain_timer.stop()
|
curtain_timer.stop()
|
||||||
@@ -120,7 +137,7 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect
|
|||||||
curtain.texture = CURTAIN_FRAMES[curtain_idx[0]]
|
curtain.texture = CURTAIN_FRAMES[curtain_idx[0]]
|
||||||
curtain.visible = true
|
curtain.visible = true
|
||||||
else:
|
else:
|
||||||
# Completamente chiuso: resta fermo su frame 00
|
# Completamente chiuso
|
||||||
curtain.texture = CURTAIN_FRAMES[0]
|
curtain.texture = CURTAIN_FRAMES[0]
|
||||||
curtain_dir[0] = 0
|
curtain_dir[0] = 0
|
||||||
curtain_timer.stop()
|
curtain_timer.stop()
|
||||||
@@ -129,7 +146,7 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect
|
|||||||
|
|
||||||
# Lucine a inseguimento
|
# Lucine a inseguimento
|
||||||
var lights := TextureRect.new()
|
var lights := TextureRect.new()
|
||||||
lights.name = "HoverGarland"
|
lights.name = color_id.capitalize() + "Garland"
|
||||||
lights.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
lights.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||||
lights.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
lights.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
lights.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
lights.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
@@ -140,6 +157,7 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect
|
|||||||
|
|
||||||
var lights_idx := [0]
|
var lights_idx := [0]
|
||||||
var lights_timer := Timer.new()
|
var lights_timer := Timer.new()
|
||||||
|
lights_timer.name = color_id.capitalize() + "GarlandTimer"
|
||||||
lights_timer.wait_time = 1.0 / 12.5
|
lights_timer.wait_time = 1.0 / 12.5
|
||||||
lights_timer.process_mode = Node.PROCESS_MODE_ALWAYS
|
lights_timer.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||||
lights_timer.timeout.connect(func():
|
lights_timer.timeout.connect(func():
|
||||||
@@ -150,28 +168,114 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect
|
|||||||
add_child(lights_timer)
|
add_child(lights_timer)
|
||||||
lights_timer.start()
|
lights_timer.start()
|
||||||
|
|
||||||
parent_button.mouse_entered.connect(func():
|
if color_id == "blue":
|
||||||
# Avvia apertura sipario (hover in)
|
blue_curtain_dir = curtain_dir
|
||||||
curtain_dir[0] = 1
|
blue_curtain_timer = curtain_timer
|
||||||
curtain_timer.start()
|
blue_lights = lights
|
||||||
# Avvia lucine
|
elif color_id == "red":
|
||||||
lights_idx[0] = 0
|
red_curtain_dir = curtain_dir
|
||||||
lights.texture = GARLAND_FRAMES[0]
|
red_curtain_timer = curtain_timer
|
||||||
lights.visible = true
|
red_lights = lights
|
||||||
)
|
|
||||||
parent_button.mouse_exited.connect(func():
|
|
||||||
# Avvia chiusura sipario al contrario (hover out)
|
func _select_tent(which: String) -> void:
|
||||||
curtain_dir[0] = -1
|
if selected_tent == which:
|
||||||
curtain_timer.start()
|
return
|
||||||
# Spegne lucine
|
selected_tent = which
|
||||||
lights.visible = false
|
|
||||||
)
|
# Aggiorna animazioni sui tendoni
|
||||||
|
if which == "juggle":
|
||||||
|
# Attiva tendone blu
|
||||||
|
if blue_mat:
|
||||||
|
blue_mat.set_shader_parameter("hover_strength", 1.0)
|
||||||
|
blue_mat.set_shader_parameter("garland_strength", 1.0)
|
||||||
|
if blue_curtain_dir and blue_curtain_timer:
|
||||||
|
blue_curtain_dir[0] = 1
|
||||||
|
blue_curtain_timer.start()
|
||||||
|
if blue_lights:
|
||||||
|
blue_lights.visible = true
|
||||||
|
|
||||||
|
# Spegne e richiude tendone rosso
|
||||||
|
if red_mat:
|
||||||
|
red_mat.set_shader_parameter("hover_strength", 0.0)
|
||||||
|
red_mat.set_shader_parameter("garland_strength", 0.0)
|
||||||
|
if red_curtain_dir and red_curtain_timer:
|
||||||
|
red_curtain_dir[0] = -1
|
||||||
|
red_curtain_timer.start()
|
||||||
|
if red_lights:
|
||||||
|
red_lights.visible = false
|
||||||
|
|
||||||
|
elif which == "gym":
|
||||||
|
# Attiva tendone rosso
|
||||||
|
if red_mat:
|
||||||
|
red_mat.set_shader_parameter("hover_strength", 1.0)
|
||||||
|
red_mat.set_shader_parameter("garland_strength", 1.0)
|
||||||
|
if red_curtain_dir and red_curtain_timer:
|
||||||
|
red_curtain_dir[0] = 1
|
||||||
|
red_curtain_timer.start()
|
||||||
|
if red_lights:
|
||||||
|
red_lights.visible = true
|
||||||
|
|
||||||
|
# Spegne e richiude tendone blu
|
||||||
|
if blue_mat:
|
||||||
|
blue_mat.set_shader_parameter("hover_strength", 0.0)
|
||||||
|
blue_mat.set_shader_parameter("garland_strength", 0.0)
|
||||||
|
if blue_curtain_dir and blue_curtain_timer:
|
||||||
|
blue_curtain_dir[0] = -1
|
||||||
|
blue_curtain_timer.start()
|
||||||
|
if blue_lights:
|
||||||
|
blue_lights.visible = false
|
||||||
|
|
||||||
|
# Transizione del piedone: scende e risale con le nuove info
|
||||||
|
_transition_bottom_bar(which)
|
||||||
|
|
||||||
|
|
||||||
|
func _transition_bottom_bar(which: String) -> void:
|
||||||
|
if not is_instance_valid(piedone):
|
||||||
|
return
|
||||||
|
|
||||||
|
var v_height := get_viewport_rect().size.y
|
||||||
|
var hidden_y := v_height * 0.29
|
||||||
|
var target_y := 0.0
|
||||||
|
|
||||||
|
if is_instance_valid(piedone_tween) and piedone_tween.is_running():
|
||||||
|
piedone_tween.kill()
|
||||||
|
|
||||||
|
piedone_tween = create_tween()
|
||||||
|
piedone_tween.set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
|
||||||
|
|
||||||
|
# Se è già visibile/alzato, scende prima di risalire
|
||||||
|
if piedone.position.y < hidden_y * 0.5:
|
||||||
|
piedone_tween.tween_property(piedone, "position:y", hidden_y, 0.25).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
|
||||||
|
piedone_tween.tween_callback(func(): _update_piedone_content(which))
|
||||||
|
piedone_tween.tween_property(piedone, "position:y", v_height * 0.025, 0.45).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
||||||
|
piedone_tween.tween_property(piedone, "position:y", target_y, 0.25).set_trans(Tween.TRANS_BOUNCE).set_ease(Tween.EASE_OUT)
|
||||||
|
else:
|
||||||
|
# Parte da nascosto: aggiorna subito e sale
|
||||||
|
_update_piedone_content(which)
|
||||||
|
piedone_tween.tween_property(piedone, "position:y", v_height * 0.025, 0.60).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
||||||
|
piedone_tween.tween_property(piedone, "position:y", target_y, 0.35).set_trans(Tween.TRANS_BOUNCE).set_ease(Tween.EASE_OUT)
|
||||||
|
|
||||||
|
|
||||||
|
func _update_piedone_content(which: String) -> void:
|
||||||
|
if which == "juggle":
|
||||||
|
piedone_title.text = "JUGGLEBOARD"
|
||||||
|
piedone_desc.text = "Allena ritmo e coordinazione con le biglie e i lanci a bersaglio."
|
||||||
|
elif which == "gym":
|
||||||
|
piedone_title.text = "PALESTRA DI GIOCOLERIA"
|
||||||
|
piedone_desc.text = "Scopri gli attrezzi del circo: clave, palline, piatti e rola bola."
|
||||||
|
|
||||||
|
|
||||||
|
func _on_play_pressed() -> void:
|
||||||
|
if selected_tent == "juggle":
|
||||||
|
juggle_requested.emit(blue_tent_control)
|
||||||
|
elif selected_tent == "gym":
|
||||||
|
gym_requested.emit(red_tent_control)
|
||||||
|
|
||||||
|
|
||||||
func _add_bottom_bar() -> void:
|
func _add_bottom_bar() -> void:
|
||||||
# Il piedone entra dal basso come un unico blocco; la scritta resta
|
# Il piedone parte abbassato/nascosto all'avvio.
|
||||||
# invisibile fino a quando il rimbalzo della barra non è terminato.
|
piedone = Control.new()
|
||||||
var piedone := Control.new()
|
|
||||||
piedone.name = "Piedone"
|
piedone.name = "Piedone"
|
||||||
piedone.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
piedone.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
piedone.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
piedone.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||||
@@ -190,17 +294,40 @@ func _add_bottom_bar() -> void:
|
|||||||
piedone.add_child(rule)
|
piedone.add_child(rule)
|
||||||
MenuUI.set_normalized_rect(rule, Vector2(0.50, item[0]), Vector2(1.0, item[1] / 720.0))
|
MenuUI.set_normalized_rect(rule, Vector2(0.50, item[0]), Vector2(1.0, item[1] / 720.0))
|
||||||
|
|
||||||
var label := MenuUI.add_label(piedone, "Tocca un tendone e scopri il gioco!", Vector2(0.38, 0.89), Vector2(0.66, 0.10), 24)
|
# Titolo del gioco selezionato
|
||||||
label.modulate.a = 0.0
|
piedone_title = MenuUI.add_label(piedone, "", Vector2(0.28, 0.84), Vector2(0.46, 0.07), 24)
|
||||||
|
piedone_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||||
|
|
||||||
|
# Descrizione del gioco
|
||||||
|
piedone_desc = Label.new()
|
||||||
|
piedone_desc.text = ""
|
||||||
|
piedone_desc.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||||
|
piedone_desc.vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
||||||
|
piedone_desc.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||||
|
piedone_desc.add_theme_font_override("font", MenuUI.DISPLAY_FONT)
|
||||||
|
piedone_desc.add_theme_font_size_override("font_size", 16)
|
||||||
|
piedone_desc.add_theme_color_override("font_color", Color("#423832"))
|
||||||
|
piedone_desc.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
piedone.add_child(piedone_desc)
|
||||||
|
MenuUI.set_normalized_rect(piedone_desc, Vector2(0.28, 0.92), Vector2(0.46, 0.08))
|
||||||
|
|
||||||
|
# Pulsante GIOCA sul lato destro del piedone
|
||||||
|
piedone_play = TextureButton.new()
|
||||||
|
piedone_play.ignore_texture_size = true
|
||||||
|
piedone_play.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
|
piedone_play.texture_normal = PLAY_BUTTON
|
||||||
|
piedone_play.texture_hover = PLAY_BUTTON
|
||||||
|
piedone_play.texture_pressed = PLAY_BUTTON
|
||||||
|
piedone_play.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||||
|
piedone_play.mouse_entered.connect(func(): piedone_play.modulate = Color(1.08, 1.08, 1.08, 1.0))
|
||||||
|
piedone_play.mouse_exited.connect(func(): piedone_play.modulate = Color.WHITE)
|
||||||
|
piedone_play.pressed.connect(_on_play_pressed)
|
||||||
|
piedone.add_child(piedone_play)
|
||||||
|
MenuUI.set_normalized_rect(piedone_play, Vector2(0.79, 0.88), Vector2(0.24, 0.13))
|
||||||
|
|
||||||
|
# Parte nascosto sotto lo schermo
|
||||||
var viewport_height := get_viewport_rect().size.y
|
var viewport_height := get_viewport_rect().size.y
|
||||||
piedone.position.y = viewport_height * 0.29
|
piedone.position.y = viewport_height * 0.29
|
||||||
var tween := create_tween()
|
|
||||||
# Il menu viene messo in pausa dalla shell: l'ingresso deve continuare comunque.
|
|
||||||
tween.set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
|
|
||||||
tween.tween_property(piedone, "position:y", viewport_height * 0.025, 0.85).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
|
||||||
tween.tween_property(piedone, "position:y", 0.0, 0.42).set_trans(Tween.TRANS_BOUNCE).set_ease(Tween.EASE_OUT)
|
|
||||||
tween.tween_property(label, "modulate:a", 1.0, 0.32).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
|
|
||||||
|
|
||||||
|
|
||||||
func _add_sign() -> void:
|
func _add_sign() -> void:
|
||||||
|
|||||||
Reference in New Issue
Block a user