From 8ed0837c9d782fb7d00b8d7d0f6200ba98fa3dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=A8=E8=90=BD=E5=9F=BA=E5=9B=B4=E8=99=BE?= <3161880837@qq.com> Date: Thu, 13 Nov 2025 22:23:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=A4=9A=E4=BA=BA=E6=B8=B8=E6=88=8F):=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=A4=9A=E4=BA=BA=E6=B8=B8=E6=88=8F=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=90=8C=E6=AD=A5=E5=92=8C=E5=8D=95=E6=9C=BA/?= =?UTF-8?q?=E5=A4=9A=E4=BA=BA=E6=A8=A1=E5=BC=8F=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加多人游戏状态管理,包括连接状态和玩家名称同步 修改WorldManager和EntityBase以支持多人游戏逻辑 在Starter面板中实现单机和多人游戏启动功能 --- project.godot | 1 - scripts/Contents/Panels/Starter.gd | 11 ++++++++--- scripts/Statemachine/EntityBase.gd | 14 +++++++++++++- scripts/Tools/Managers/MultiplayerState.gd | 3 +++ scripts/Tools/Managers/WorldManager.gd | 9 +++++---- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/project.godot b/project.godot index c80f79c..eebf13a 100644 --- a/project.godot +++ b/project.godot @@ -19,7 +19,6 @@ config/icon="res://icon.svg" window/size/viewport_width=1280 window/size/viewport_height=720 -window/size/mode=2 [dotnet] diff --git a/scripts/Contents/Panels/Starter.gd b/scripts/Contents/Panels/Starter.gd index 355d026..db9e6d2 100644 --- a/scripts/Contents/Panels/Starter.gd +++ b/scripts/Contents/Panels/Starter.gd @@ -53,9 +53,16 @@ func rebuildAllPlayers(playerNames: Array[String]): addPlayerName(i) @rpc("any_peer") func startMultiplayerGame(): + MultiplayerState.isMultiplayer = true + WorldManager.rootNode.multiplayer.multiplayer_peer = MultiplayerState.connection MultiplayerState.playerName = playerNameInput.text + MultiplayerState.connection = multiplayer.multiplayer_peer for i in getPlayerNames(): EntityBase.generatePlayer(i) + UIState.closeCurrentPanel() +func startSingleplayerGame(): + MultiplayerState.isMultiplayer = false + EntityBase.generatePlayer(playerNameInput.text) Wave.next() UIState.closeCurrentPanel() @@ -74,9 +81,7 @@ func _ready(): ) startSingleplayerBtn.pressed.connect( func(): - EntityBase.generatePlayer(playerNameInput.text) - Wave.next() - UIState.closeCurrentPanel() + startSingleplayerGame() ) startMultiplayerBtn.pressed.connect( func(): diff --git a/scripts/Statemachine/EntityBase.gd b/scripts/Statemachine/EntityBase.gd index 94cb0f5..aa7f6ef 100644 --- a/scripts/Statemachine/EntityBase.gd +++ b/scripts/Statemachine/EntityBase.gd @@ -105,6 +105,7 @@ var currentStage: int = 0 var spawnTime: float = 0 func _ready(): + multiplayer.multiplayer_peer = MultiplayerState.connection if useStatic: texture = texture.get_node("staticAnimation") spawnTime = WorldManager.getTime() @@ -170,7 +171,7 @@ func _physics_process(_delta: float) -> void: velocity = Vector2.ZERO if (isPlayer() or is_instance_valid(currentFocusedBoss)) and not charginup and canRunAi: if isPlayer(): - if MultiplayerState.playerName == displayName: + if MultiplayerState.playerName == displayName or not MultiplayerState.isMultiplayer: ai() else: ai() @@ -180,6 +181,13 @@ func _physics_process(_delta: float) -> void: storeEnergy(randf_range(0.01, 0.05 + fields.get(FieldStore.Entity.ENERGY_REGENERATION) - 1), true) trailParticle.emitting = trailing +# 同步状态 +@rpc("any_peer") +func syncPosition(player: String, newPosition: Vector2, newVelocity: Vector2): + if player != displayName: return + position = newPosition + velocity = newVelocity + # 通用方法 func rebuildWeaponIcons(): if isPlayer(): @@ -216,6 +224,9 @@ func move(direction: Vector2, isSprinting: bool = false): var currentDirection = sign(direction.x) if currentDirection != 0: lastDirection = currentDirection + if MultiplayerState.isMultiplayer: + print("test") + syncPosition.rpc(displayName, position, velocity) func getSprintInitialDisplace(): return displace(velocity) * sprintMultiplier func getSprintProgress(): @@ -437,6 +448,7 @@ func kill(): static func generatePlayer(playerName: String): var player = generate(ComponentManager.getCharacter("Rooster"), Vector2.ZERO, false, false, true) player.displayName = playerName + player.name = "Player_%s" % playerName return player static func generate( entity: PackedScene, diff --git a/scripts/Tools/Managers/MultiplayerState.gd b/scripts/Tools/Managers/MultiplayerState.gd index 95cccfa..3986fc5 100644 --- a/scripts/Tools/Managers/MultiplayerState.gd +++ b/scripts/Tools/Managers/MultiplayerState.gd @@ -20,9 +20,12 @@ static var stateColorMap = { ConnectionState.CONNECTED_CLIENT: Color.GREEN, } +static var isMultiplayer: bool = false static var state: ConnectionState = ConnectionState.DISCONNECTED static var playerName: String +static var connection: ENetMultiplayerPeer + static var maxPlayer: int = 10 static func isConnected(): diff --git a/scripts/Tools/Managers/WorldManager.gd b/scripts/Tools/Managers/WorldManager.gd index c5eddfc..7c4c8f4 100644 --- a/scripts/Tools/Managers/WorldManager.gd +++ b/scripts/Tools/Managers/WorldManager.gd @@ -1,7 +1,7 @@ extends Node2D class_name WorldManager -static var rootNode: Node2D +static var rootNode: WorldManager static var tree: SceneTree static var runningTime: int = 0 static var peer: ENetMultiplayerPeer @@ -10,11 +10,12 @@ func _ready(): tree = get_tree() rootNode = self ComponentManager.init() - peer = ENetMultiplayerPeer.new() func _physics_process(delta): runningTime += delta * 1000 - if EntityBase.mobCount() == 0 and runningTime > 3000: - UIState.setPanel("MakeFeed") + if multiplayer.is_server() or not MultiplayerState.isMultiplayer: + if EntityBase.mobCount() == 0 and runningTime > 3000: + Wave.next() + UIState.setPanel("MakeFeed") static func getTime(): return runningTime