From 84a15c7d4c0b21701c26a19859b6863752506100 Mon Sep 17 00:00:00 2001 From: enne2 Date: Thu, 10 Sep 2026 23:02:00 +0200 Subject: [PATCH] feat: trigger tent animations and piedone transition on click selection --- menus/scripts/screens/p1_home_screen.gd | 243 ++++++++++++++++++------ 1 file changed, 185 insertions(+), 58 deletions(-) diff --git a/menus/scripts/screens/p1_home_screen.gd b/menus/scripts/screens/p1_home_screen.gd index 13898a2..0fb7e81 100644 --- a/menus/scripts/screens/p1_home_screen.gd +++ b/menus/scripts/screens/p1_home_screen.gd @@ -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 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 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 := [ 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)) _add_sign() - # Solo il tendone blu di riferimento attiva lo shader delle lucine in hover. - var blue := _add_tent_button(BLUE_TENT, Vector2(0.29, 0.46), true) - blue.pressed.connect(func(): juggle_requested.emit(blue)) - var red := _add_tent_button(RED_TENT, Vector2(0.71, 0.46), false) - red.pressed.connect(func(): gym_requested.emit(red)) + # Costruzione dei due tendoni selezionabili al click (entrambi con luci e sipario) + var blue := _add_tent_button(BLUE_TENT, Vector2(0.29, 0.46), "juggle") + blue_tent_control = blue + blue.pressed.connect(func(): _select_tent("juggle")) + + 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() 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()) -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 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.tooltip_text = "Apri questo percorso" + button.tooltip_text = "Seleziona questo percorso" - # Glow stella su entrambi i tendoni al passaggio del mouse - button.mouse_entered.connect(func(): - mat.set_shader_parameter("hover_strength", 1.0) - if has_lights: - mat.set_shader_parameter("garland_strength", 1.0) - ) - 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) + if tent_id == "juggle": + blue_mat = mat + _setup_tent_interactive(button, center, "blue") + elif tent_id == "gym": + red_mat = mat + _setup_tent_interactive(button, center, "red") return button -func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vector2) -> void: - # Sipario: parte chiuso (frame 0). All'hover-in si apre (0 -> 6). - # All'hover-out si richiude al contrario (6 -> 0). +func _setup_tent_interactive(parent_button: TextureButton, center: Vector2, color_id: String) -> void: + # Sipario: parte chiuso (frame 0). Alla selezione si apre (0 -> 6). + # Alla deselezione si richiude al contrario (6 -> 0). var curtain := TextureRect.new() - curtain.name = "Curtain" + curtain.name = color_id.capitalize() + "Curtain" curtain.expand_mode = TextureRect.EXPAND_IGNORE_SIZE curtain.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED 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) 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_timer := Timer.new() + curtain_timer.name = color_id.capitalize() + "CurtainTimer" curtain_timer.wait_time = 1.0 / 12.5 curtain_timer.process_mode = Node.PROCESS_MODE_ALWAYS + var curtain_idx := [0] curtain_timer.timeout.connect(func(): if curtain_dir[0] == 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.visible = true else: - # Completamente aperto: frame 06 è vuoto/trasparente + # Completamente aperto curtain.texture = CURTAIN_FRAMES[curtain_idx[0]] curtain_dir[0] = 0 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.visible = true else: - # Completamente chiuso: resta fermo su frame 00 + # Completamente chiuso curtain.texture = CURTAIN_FRAMES[0] curtain_dir[0] = 0 curtain_timer.stop() @@ -129,7 +146,7 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect # Lucine a inseguimento var lights := TextureRect.new() - lights.name = "HoverGarland" + lights.name = color_id.capitalize() + "Garland" lights.expand_mode = TextureRect.EXPAND_IGNORE_SIZE lights.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED 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_timer := Timer.new() + lights_timer.name = color_id.capitalize() + "GarlandTimer" lights_timer.wait_time = 1.0 / 12.5 lights_timer.process_mode = Node.PROCESS_MODE_ALWAYS lights_timer.timeout.connect(func(): @@ -150,28 +168,114 @@ func _setup_hover_curtain_and_garland(parent_button: TextureButton, center: Vect add_child(lights_timer) lights_timer.start() - parent_button.mouse_entered.connect(func(): - # Avvia apertura sipario (hover in) - curtain_dir[0] = 1 - curtain_timer.start() - # Avvia lucine - lights_idx[0] = 0 - lights.texture = GARLAND_FRAMES[0] - lights.visible = true - ) - parent_button.mouse_exited.connect(func(): - # Avvia chiusura sipario al contrario (hover out) - curtain_dir[0] = -1 - curtain_timer.start() - # Spegne lucine - lights.visible = false - ) + if color_id == "blue": + blue_curtain_dir = curtain_dir + blue_curtain_timer = curtain_timer + blue_lights = lights + elif color_id == "red": + red_curtain_dir = curtain_dir + red_curtain_timer = curtain_timer + red_lights = lights + + +func _select_tent(which: String) -> void: + if selected_tent == which: + return + selected_tent = which + + # 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: - # Il piedone entra dal basso come un unico blocco; la scritta resta - # invisibile fino a quando il rimbalzo della barra non è terminato. - var piedone := Control.new() + # Il piedone parte abbassato/nascosto all'avvio. + piedone = Control.new() piedone.name = "Piedone" piedone.mouse_filter = Control.MOUSE_FILTER_IGNORE piedone.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) @@ -190,17 +294,40 @@ func _add_bottom_bar() -> void: piedone.add_child(rule) 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) - label.modulate.a = 0.0 + # Titolo del gioco selezionato + 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 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: