开始菜单、玩家选择、脸部绘制

This commit is contained in:
2026-10-02 12:06:28 +08:00
parent fbf00cf11f
commit 698cb02c21
26 changed files with 1419 additions and 21 deletions
+36 -5
View File
@@ -18,6 +18,9 @@ const MAX_PLAYERS: int = 8
const DEFAULT_ADDRESS: String = "127.0.0.1"
## 所有玩家节点都会加入这个组,方便整批清场
const PLAYER_GROUP: String = "net_player"
## 开局后要进的世界场景,以及断开后要回的入口场景
const WORLD_SCENE: String = "res://world/main.tscn"
const MENU_SCENE: String = "res://ui/main_menu.tscn"
var _spawner: MultiplayerSpawner = null
@@ -41,8 +44,20 @@ func _ready() -> void:
# ---------------- 对外接口 ----------------
## 世界根节点在 _ready 里调用,把 MultiplayerSpawner 托管给 Net。
##
## 世界是「开局之后」才加载的(入口是开始菜单),所以这里得把已经连上的玩家补生成一遍 ——
## 否则主机在菜单里就开好了,切进世界时一个角色都不会出现。
func bind_spawner(spawner: MultiplayerSpawner) -> void:
_spawner = spawner
if multiplayer.is_server():
call_deferred("_spawn_player", 1)
for id in multiplayer.get_peers():
call_deferred("_spawn_player", id)
## 菜单那边用它开关「联机」面板 —— 面板默认是显示的,会盖住入口菜单。
func set_menu_visible(on: bool) -> void:
_menu.visible = on
## 创建主机。ENet 是客户端-服务器模型,主机同时是服务器与玩家。
@@ -55,8 +70,8 @@ func host_game() -> void:
multiplayer.multiplayer_peer = peer
_show_game_ui()
print("[Net] 主机已启动,端口 %d" % PORT)
# 服务器自己也要一个角色。延后一帧,等各端场景就绪。
call_deferred("_spawn_player", 1)
# 入口是开始菜单,世界这时还没加载 —— 切过去,角色由 bind_spawner 补生成
call_deferred("_enter_world")
## 加入主机。address 为主机在局域网内的内网 IP。
@@ -74,13 +89,28 @@ func join_game(address: String = DEFAULT_ADDRESS) -> void:
print("[Net] 正在连接 %s:%d" % [target, PORT])
## 断开并清场,回到主菜单。
## 断开并清场,回入口菜单。
func leave_game() -> void:
multiplayer.multiplayer_peer = null
_clear_players()
# 世界一卸载 spawner 就跟着没了,留着引用会指向已释放的节点
_spawner = null
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
_show_menu_ui()
_set_status("已断开")
call_deferred("_go_to", MENU_SCENE)
## 切到世界场景。已经在里面就不重复切
func _enter_world() -> void:
_go_to(WORLD_SCENE)
func _go_to(path: String) -> void:
var current := get_tree().current_scene
if current != null and current.scene_file_path == path:
return
get_tree().change_scene_to_file(path)
# ---------------- 网络事件 ----------------
@@ -99,6 +129,7 @@ func _on_peer_disconnected(id: int) -> void:
func _on_connected_to_server() -> void:
_show_game_ui()
print("[Net] 已连接,等待主机生成角色")
call_deferred("_enter_world")
func _on_connection_failed() -> void:
@@ -117,7 +148,7 @@ func _on_server_disconnected() -> void:
# ---------------- 玩家生成与回收 ----------------
func _spawn_player(peer_id: int) -> void:
if _spawner == null or not multiplayer.is_server():
if not is_instance_valid(_spawner) or not multiplayer.is_server():
return
var parent := _spawner.get_node_or_null(_spawner.spawn_path)
if parent == null or parent.has_node(str(peer_id)):
@@ -126,7 +157,7 @@ func _spawn_player(peer_id: int) -> void:
func _despawn_player(peer_id: int) -> void:
if _spawner == null:
if not is_instance_valid(_spawner):
return
var parent := _spawner.get_node_or_null(_spawner.spawn_path)
if parent == null: