extends Control ## 游戏开始菜单 —— 项目的入口场景(project.godot 的 run/main_scene)。 ## ## 「开始游戏」→ 角色选择 → 确定 = 开主机并进世界。这个项目是客户端-服务器模型, ## 单人玩也是本机开服(没有单独的「离线模式」)。 ## 「联机」把 Net 的创建/加入面板放出来,那边选完同样会切进世界。 ## ## 进世界、回菜单这两件事都归 Net 管(见 net.gd 的 _enter_world / leave_game), ## 菜单只负责「按了哪个按钮」。 ## ## 接线示例(放在外层): ## menu.settings_pressed.connect(_on_settings) ## menu.quit_pressed.connect(get_tree().quit) const CHARACTER_SELECT := preload("res://ui/character_select.tscn") ## 用节点路径而不是全局标识符访问单例:autoload 的全局名只在引擎启动时注册, ## 这样写不依赖注册时机(和 world/main.gd 一致) const NET_PATH := "/root/Net" signal start_pressed signal multiplayer_pressed signal settings_pressed signal quit_pressed var _net: Node var _character_select: Control func _ready() -> void: # 从游戏内退回菜单时鼠标可能还是被捕获的,先放出来 —— 不然菜单点不动 Input.mouse_mode = Input.MOUSE_MODE_VISIBLE _net = get_node_or_null(NET_PATH) # Net 那个「联机测试」面板默认可见(CanvasLayer layer 20),会正好盖在菜单中间 if _net != null: _net.set_menu_visible(false) %StartButton.pressed.connect(_on_start_pressed) %MultiplayerButton.pressed.connect(_on_multiplayer_pressed) %SettingsButton.pressed.connect(settings_pressed.emit) %QuitButton.pressed.connect(quit_pressed.emit) ## 「开始游戏」:先把信号发出去(外部想接就接),再把角色选择盖上来 func _on_start_pressed() -> void: start_pressed.emit() if _character_select == null: _character_select = CHARACTER_SELECT.instantiate() add_child(_character_select) _character_select.confirmed.connect(_on_character_confirmed) _character_select.back_pressed.connect(_close_character_select) _character_select.visible = true ## 角色选择点「确定」:脸这时已经写进 user:// 了,开主机,Net 负责切进世界 func _on_character_confirmed() -> void: _close_character_select() if _net != null: _net.host_game() func _on_multiplayer_pressed() -> void: multiplayer_pressed.emit() # 暂时直接把 Net 那个创建/加入面板放出来顶着 —— 换成正经的联机子页后删掉这行 if _net != null: _net.set_menu_visible(true) func _close_character_select() -> void: if _character_select != null: _character_select.visible = false