Skill
godot-tscn-format
Godot 4.x .tscn 场景文件纯文本格式规范与 AI 操作指南 — 文件结构、资源引用、 Transform 变换、属性值格式、信号连接,以及 AI 直接读写 .tscn 文件的操作方法。
Godot 4 多人游戏核心模式,包括场景管理、玩家生命周期、死亡复活机制。
$ npx -y skills add 925236118/AlphaAgent --skill godot-online-multiplayer --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/godot-online-multiplayerContext preview
The summary Claude sees to decide when to auto-load this skill.
Godot 4 多人游戏核心模式,包括场景管理、玩家生命周期、死亡复活机制。
name: godot-online-multiplayer description: Godot 4 多人游戏核心模式,包括场景管理、玩家生命周期、死亡复活机制。
Godot 4 多人游戏核心模式,涵盖场景管理、玩家生命周期、死亡复活等机制。
MultiplayerHost (服务器/主机) ├── MultiplayerSpawner (自动生成节点) ├── MultiplayerSynchronizer (状态同步) └── PlayerManager (玩家管理) MultiplayerPeers (客户端/对等端) ├── NetworkedMultiplayerENet (网络连接) └── Player instances (同步的玩家)
# main.tscn 场景结构 # Main (Node) # ├── GameManager (Autoload) # ├── MultiplayerSpawner (自动生成玩家) # ├── World (Node2D) # │ ├── SpawnPoints (Node) # │ └── Enemies (Node) # └── UI (CanvasLayer)
# player.tscn 场景结构 # Player (CharacterBody2D) # ├── Sprite2D # ├── CollisionShape2D # ├── HealthComponent # ├── HitboxComponent # ├── NameLabel (Label) # └── HealthBar (ProgressBar)
# PlayerSpawner.gd
class_name PlayerSpawner
extends MultiplayerSpawner
## 自动生成玩家节点
## 当对等端连接时自动生成玩家实例
signal player_spawned(player: Node, peer_id: int)
signal player_despawned(player: Node, peer_id: int)
@export var player_scene: PackedScene
func _ready() -> void:
# 设置生成路径
spawn_path = ^"/root/Main/Players"
# 连接信号
spawned.connect(_on_spawned)
despawned.connect(_on_despawned)
func _on_spawned(node: Node) -> void:
var peer_id := multiplayer.get_remote_sender_id()
print("玩家生成: %s (Peer ID: %d)" % [node.name, peer_id])
player_spawned.emit(node, peer_id)
func _on_despawned(node: Node) -> void:
var peer_id := multiplayer.get_remote_sender_id()
print("玩家销毁: %s (Peer ID: %d)" % [node.name, peer_id])
player_despawned.emit(node, peer_id)# spawn_manager.gd
class_name SpawnManager
extends Node
## 管理玩家生成逻辑
@export var player_scene: PackedScene
@export var spawn_points: Array[Marker2D] = []
var _spawn_points_container: Node2D
func _ready() -> void:
_spawn_points_container = $SpawnPoints
func get_spawn_position(peer_id: int) -> Vector2:
"""根据peer_id获取生成位置"""
if spawn_points.is_empty():
return Vector2.ZERO
# 使用 peer_id 哈希选择生成点,实现均衡分布
var index := peer_id % spawn_points.size()
var spawn_point := spawn_points[index]
if spawn_point is Marker2D:
return spawn_point.global_position
return spawn_point.global_position if spawn_point.has_node(".") else Vector2.ZERO
func spawn_player(peer_id: int, parent: Node) -> Node:
"""生成玩家节点"""
var player := player_scene.instantiate()
# 设置玩家名称为 peer_id
player.name = str(peer_id)
# 设置初始位置
player.global_position = get_spawn_position(peer_id)
# 配置玩家
if player.has_method("setup"):
player.setup(peer_id)
parent.add_child(player)
# 只在服务器上设置网络主人
if multiplayer.is_server():
player.set_multiplayer_authority(peer_id)
return player
func despawn_player(peer_id: int, parent: Node) -> void:
"""销毁玩家节点"""
var player := parent.get_node_or_null(str(peer_id))
if player:
player.queue_free()# game_manager.gd (Autoload)
extends Node
signal player_joined(peer_id: int)
signal player_left(peer_id: int)
signal game_started
signal game_ended(winner_id: int)
enum GameState { WAITING, PLAYING, GAME_OVER }
var game_state: GameState = GameState.WAITING
var players: Dictionary = {} # peer_id -> PlayerData
var _min_players: int = 1
var _max_players: int = 4
func _ready() -> void:
# 设置网络回调
multiplayer.peer_connected.connect(_on_peer_connected)
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
# 如果是服务器,启动游戏循环
if multiplayer.is_server():
_check_start_game()
func _on_peer_connected(peer_id: int) -> void:
print("玩家连接: %d" % peer_id)
# 创建玩家数据
var player_data := PlayerData.new()
player_data.peer_id = peer_id
player_data.name = "Player_%d" % peer_id
player_data.is_alive = true
player_data.score = 0
players[peer_id] = player_data
# 通知所有客户端有新玩家加入
rpc("_sync_player_joined", peer_id, player_data.to_dict())
player_joined.emit(peer_id)
# 检查是否可以开始游戏
_check_start_game()
func _on_peer_disconnected(peer_id: int) -> void:
print("玩家断开: %d" % peer_id)
# 清理玩家数据
var player_data := players.get(peer_id)
if player_data:
player_data.free()
players.erase(peer_id)
# 通知所有客户端
rpc("_sync_player_left", peer_id)
player_left.emit(peer_id)
# 检查游戏是否结束
if game_state == GameState.PLAYING and players.size() < 2:
_end_game(0) # 剩余玩家获胜
@rpc(call_local = true)
func _sync_player_joined(peer_id: int, data: Dictionary) -> void:
if not players.has(peer_id):
var player_data := PlayerData.new()
player_data.from_dict(data)
players[peer_id] = player_data
@rpc(call_local = true)
func _sync_player_left(peer_id: int) -> void:
var player_data := players.get(peer_id)
if player_data:
player_data.free()
players.erase(peer_id)
func _check_start_game() -> void:
if game_state == GameState.WAITING and players.size() >= _min_players:
start_game()
func start_game() -> void:
game_state = GameState.PLAYING
game_started.emit()
# 重置所有玩家状态
for peer_id in players.keys():
var data := players[peer_id]
data.is_alive = true
data.lives = 3
data.score = 0
rpc("_sync_game_state", GameState.PLAYING)
@rpc(call_local = true)
func _sync_game_state(state: GameState) -> void:
game_state = state
func _end_game(winner_id: int) -> void:
game_state = GameState.GAME_OVER
game_ended.emit(winner_id)
rpc("_sync_game_state", GameState.GAME_OVER)
rpc("_sync_winner", winner_id)
@rpc(call_local = true)
func _sync_winner(winner_id: int) -> void:
pass # UI显示胜利者
# PlayerData.gd
class_nameGodot 4.x .tscn 场景文件纯文本格式规范与 AI 操作指南 — 文件结构、资源引用、 Transform 变换、属性值格式、信号连接,以及 AI 直接读写 .tscn 文件的操作方法。
Godot 4 Buff系统完整实现,支持状态效果管理、持续时间、循环效果、层叠机制等。使用Resource+Component架构。