Files
agame/ui/main_menu.gd
T

71 lines
2.6 KiB
GDScript

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