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")