创建新工程

This commit is contained in:
moyin
2025-12-05 19:00:14 +08:00
commit ff4fa5fffd
227 changed files with 32804 additions and 0 deletions

279
scripts/WorldManager.gd Normal file
View File

@@ -0,0 +1,279 @@
extends Node
class_name WorldManager
## 世界管理器
## 管理游戏世界中的所有角色和对象
# 角色管理
var characters: Dictionary = {} # character_id -> CharacterController
var player_character: CharacterController = null
# 场景引用
var character_container: Node2D = null
# 预加载的角色场景
var player_character_scene: PackedScene = null
var remote_character_scene: PackedScene = null
# 信号
signal character_spawned(character_id: String, character: CharacterController)
signal character_removed(character_id: String)
signal character_state_updated(character_id: String)
func _ready():
"""初始化世界管理器"""
print("WorldManager initialized")
## 设置角色容器
func set_character_container(container: Node2D):
"""
设置角色容器节点
@param container: 用于放置角色的 Node2D 容器
"""
character_container = container
## 生成角色
func spawn_character(character_data: Dictionary, is_player: bool = false) -> CharacterController:
"""
在世界中生成角色
@param character_data: 角色数据
@param is_player: 是否为玩家角色
@return: 生成的角色控制器
"""
if not character_container:
push_error("Character container not set")
return null
var character_id = character_data.get(CharacterData.FIELD_ID, "")
if character_id.is_empty():
push_error("Character data missing ID")
return null
# 检查是否已存在
if characters.has(character_id):
push_warning("Character already exists: ", character_id)
return characters[character_id]
# 创建角色实例
var character: CharacterController
if is_player:
# 玩家角色(将在任务 11 中使用场景)
character = CharacterController.new()
character.name = "PlayerCharacter_" + character_id
else:
# 远程角色
character = CharacterController.new()
character.name = "RemoteCharacter_" + character_id
# 初始化角色
character.initialize(character_data)
# 添加到容器
character_container.add_child(character)
# 记录到字典
characters[character_id] = character
# 如果是玩家角色,保存引用
if is_player:
player_character = character
# 发射信号
character_spawned.emit(character_id, character)
print("Character spawned: ", character_id, " (player: ", is_player, ")")
return character
## 移除角色
func remove_character(character_id: String) -> void:
"""
从世界中移除角色
@param character_id: 角色 ID
"""
if not characters.has(character_id):
push_warning("Character not found: ", character_id)
return
var character = characters[character_id]
# 如果是玩家角色,清除引用
if character == player_character:
player_character = null
# 从字典中移除
characters.erase(character_id)
# 从场景树中移除
character.queue_free()
# 发射信号
character_removed.emit(character_id)
print("Character removed: ", character_id)
## 更新角色状态
func update_character_state(character_id: String, state: Dictionary) -> void:
"""
更新角色状态
@param character_id: 角色 ID
@param state: 状态数据(包含位置、在线状态等)
"""
if not characters.has(character_id):
# 检查是否是离线状态更新,如果是则忽略(角色可能已被清理)
var is_online = state.get("isOnline", true)
if not is_online:
print("Ignoring offline state update for removed character: ", character_id)
return
# 如果是在线状态但角色不存在,可能需要重新创建
print("Character not found for state update, attempting to recreate: ", character_id)
# 尝试从状态数据重新创建角色
if state.has("name") and state.has("position"):
var character_data = {
CharacterData.FIELD_ID: character_id,
CharacterData.FIELD_NAME: state.get("name", "Unknown"),
CharacterData.FIELD_POSITION: state.get("position", {"x": 0, "y": 0}),
CharacterData.FIELD_IS_ONLINE: is_online
}
spawn_character(character_data, false)
return
else:
print("Insufficient data to recreate character: ", character_id)
return
var character = characters[character_id]
# 更新位置
if state.has("position"):
var pos_data = state["position"]
var new_pos = Vector2(pos_data.get("x", 0), pos_data.get("y", 0))
character.set_position_smooth(new_pos)
# 更新在线状态
if state.has("isOnline"):
var is_online = state["isOnline"]
character.set_online_status(is_online)
# 如果角色下线,考虑延迟清理(避免频繁上下线导致的问题)
if not is_online:
print("Character went offline: ", character_id)
# 可以在这里添加延迟清理逻辑比如5分钟后清理离线角色
# _schedule_character_cleanup(character_id)
# 发射信号
character_state_updated.emit(character_id)
## 获取附近角色
func get_nearby_characters(position: Vector2, radius: float) -> Array:
"""
获取指定位置附近的角色
@param position: 中心位置
@param radius: 搜索半径
@return: 附近角色的数组
"""
var nearby: Array = []
for character in characters.values():
if character is CharacterController:
var distance = position.distance_to(character.global_position)
if distance <= radius:
nearby.append(character)
return nearby
## 获取所有角色
func get_all_characters() -> Array:
"""
获取所有角色
@return: 所有角色的数组
"""
return characters.values()
## 获取角色
func get_character(character_id: String) -> CharacterController:
"""
根据 ID 获取角色
@param character_id: 角色 ID
@return: 角色控制器,如果不存在则返回 null
"""
return characters.get(character_id, null)
## 获取玩家角色
func get_player_character() -> CharacterController:
"""
获取玩家角色
@return: 玩家角色控制器
"""
return player_character
## 处理角色上线
func handle_character_online(character_id: String) -> void:
"""
处理角色上线事件
@param character_id: 角色 ID
"""
if characters.has(character_id):
# 角色已存在,更新在线状态
var character = characters[character_id]
character.set_online_status(true)
print("Character came online: ", character_id)
else:
# 角色不存在,需要从服务器获取数据后生成
print("Character online but not spawned yet: ", character_id)
## 处理角色下线
func handle_character_offline(character_id: String) -> void:
"""
处理角色下线事件
@param character_id: 角色 ID
"""
if characters.has(character_id):
# 更新为离线状态(但不移除角色)
var character = characters[character_id]
character.set_online_status(false)
print("Character went offline: ", character_id)
else:
push_warning("Character not found for offline event: ", character_id)
## 生成或更新角色
func spawn_or_update_character(character_data: Dictionary) -> CharacterController:
"""
生成新角色或更新已存在的角色
@param character_data: 角色数据
@return: 角色控制器
"""
var character_id = character_data.get(CharacterData.FIELD_ID, "")
if character_id.is_empty():
push_error("Character data missing ID")
return null
# 检查角色是否已存在
if characters.has(character_id):
# 更新已存在的角色
update_character_state(character_id, character_data)
return characters[character_id]
else:
# 生成新角色(远程角色)
return spawn_character(character_data, false)
## 更新角色位置
func update_character_position(character_id: String, new_position: Vector2) -> void:
"""
更新角色位置
@param character_id: 角色 ID
@param new_position: 新位置
"""
if not characters.has(character_id):
push_warning("Character not found for position update: ", character_id)
return
var character = characters[character_id]
character.set_position_smooth(new_position)
## 清除所有角色
func clear_all_characters() -> void:
"""清除世界中的所有角色"""
for character_id in characters.keys():
remove_character(character_id)
print("All characters cleared")