135 lines
4.2 KiB
GDScript
135 lines
4.2 KiB
GDScript
class_name MainMenuController
|
|
extends CanvasLayer
|
|
## Coordina navigazione e transizioni tra P1, P2a e P3a.
|
|
|
|
signal mode_requested
|
|
signal gym_requested
|
|
signal exit_requested
|
|
|
|
const HOME_SCENE := preload("res://menus/scenes/p1_home.tscn")
|
|
const JUGGLE_SCENE := preload("res://menus/scenes/p2a_juggle_menu.tscn")
|
|
const GYM_SCENE := preload("res://menus/scenes/p3a_gym_menu.tscn")
|
|
|
|
var screen_root: Control
|
|
var fade: ColorRect
|
|
var menu_audio: MenuAudio
|
|
var current_screen: Control
|
|
var _transitioning := false
|
|
var _capture_enabled := false
|
|
var _capture_settled := false
|
|
|
|
|
|
func _ready() -> void:
|
|
process_mode = Node.PROCESS_MODE_ALWAYS
|
|
layer = 20
|
|
_capture_enabled = OS.get_cmdline_user_args().has("--capture-menus")
|
|
_capture_settled = OS.get_cmdline_user_args().has("--capture-settled")
|
|
_build_shell()
|
|
visible = false
|
|
|
|
|
|
func _build_shell() -> void:
|
|
var root := Control.new()
|
|
root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
root.mouse_filter = Control.MOUSE_FILTER_STOP
|
|
add_child(root)
|
|
|
|
screen_root = Control.new()
|
|
screen_root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
root.add_child(screen_root)
|
|
|
|
fade = ColorRect.new()
|
|
fade.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
fade.color = Color("#1d1720")
|
|
fade.modulate.a = 0.0
|
|
# Il fade è trasparente a riposo: non deve intercettare click o touch dei menu.
|
|
fade.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
root.add_child(fade)
|
|
|
|
menu_audio = MenuAudio.new()
|
|
add_child(menu_audio)
|
|
|
|
|
|
func show_home() -> void:
|
|
_show_direct(HOME_SCENE, "p1")
|
|
|
|
|
|
func show_juggle() -> void:
|
|
_show_direct(JUGGLE_SCENE, "p2a")
|
|
|
|
|
|
func show_gym() -> void:
|
|
_show_direct(GYM_SCENE, "p3a")
|
|
|
|
|
|
func hide_menu() -> void:
|
|
visible = false
|
|
get_tree().paused = false
|
|
|
|
|
|
func _show_direct(scene: PackedScene, capture_label: String) -> void:
|
|
visible = true
|
|
get_tree().paused = true
|
|
_replace_screen(scene)
|
|
_capture_after_frame(capture_label)
|
|
|
|
|
|
func _navigate(scene: PackedScene, capture_label: String, focal: Control = null) -> void:
|
|
if _transitioning:
|
|
return
|
|
_transitioning = true
|
|
# Durante la transizione impedisce input duplicati; torna IGNORE al termine.
|
|
fade.mouse_filter = Control.MOUSE_FILTER_STOP
|
|
menu_audio.play_tone(660.0)
|
|
var tween := create_tween()
|
|
tween.set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
|
|
if focal:
|
|
focal.pivot_offset = focal.size * 0.5
|
|
tween.tween_property(focal, "scale", Vector2(1.08, 1.08), 0.16).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
|
|
tween.parallel().tween_property(fade, "modulate:a", 0.92, 0.24)
|
|
tween.tween_callback(func(): _replace_screen(scene))
|
|
tween.tween_property(fade, "modulate:a", 0.0, 0.30)
|
|
tween.tween_callback(func():
|
|
_transitioning = false
|
|
fade.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_capture_after_frame(capture_label)
|
|
)
|
|
|
|
|
|
func _replace_screen(scene: PackedScene) -> void:
|
|
if is_instance_valid(current_screen):
|
|
current_screen.queue_free()
|
|
current_screen = scene.instantiate()
|
|
screen_root.add_child(current_screen)
|
|
_bind_screen(current_screen)
|
|
|
|
|
|
func _bind_screen(screen: Control) -> void:
|
|
if screen is P1HomeScreen:
|
|
screen.juggle_requested.connect(func(focal: Control): _navigate(JUGGLE_SCENE, "p2a", focal))
|
|
screen.gym_requested.connect(func(focal: Control): _navigate(GYM_SCENE, "p3a", focal))
|
|
screen.sign_drop_started.connect(menu_audio.play_sign_drop)
|
|
screen.sign_landed.connect(menu_audio.play_sign_bounce)
|
|
screen.exit_requested.connect(func():
|
|
menu_audio.play_tone(220.0)
|
|
exit_requested.emit()
|
|
)
|
|
elif screen is P2AJuggleMenuScreen:
|
|
screen.back_requested.connect(func(): _navigate(HOME_SCENE, "p1"))
|
|
screen.mode_requested.connect(func(): mode_requested.emit())
|
|
screen.feedback_requested.connect(menu_audio.play_tone)
|
|
elif screen is P3AGymMenuScreen:
|
|
screen.back_requested.connect(func(): _navigate(HOME_SCENE, "p1"))
|
|
screen.game_requested.connect(func(): gym_requested.emit())
|
|
screen.feedback_requested.connect(menu_audio.play_tone)
|
|
|
|
|
|
func _capture_after_frame(label: String) -> void:
|
|
if not _capture_enabled:
|
|
return
|
|
await RenderingServer.frame_post_draw
|
|
if _capture_settled:
|
|
await get_tree().create_timer(1.5, true, false, true).timeout
|
|
var image := get_viewport().get_texture().get_image()
|
|
image.save_png("/tmp/autgame_menu_%s.png" % label)
|