创建新工程
This commit is contained in:
279
scripts/WorldManager.gd
Normal file
279
scripts/WorldManager.gd
Normal 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")
|
||||
Reference in New Issue
Block a user