extends Node # ============================================================================ # SceneManager.gd - 场景管理器 # ============================================================================ # 全局单例管理器,负责场景切换和管理 # # 核心职责: # - 场景切换的统一接口 # - 场景路径映射管理 # - 场景切换过渡效果 # - 场景状态跟踪 # # 使用方式: # SceneManager.change_scene("main") # SceneManager.register_scene("custom", "res://scenes/custom.tscn") # # 注意事项: # - 作为自动加载单例,全局可访问 # - 场景切换是异步操作,支持过渡效果 # - 场景名称必须在 scene_paths 中注册 # ============================================================================ # ============ 信号定义 ============ # 场景切换完成信号 # 参数: scene_name - 切换到的场景名称 signal scene_changed(scene_name: String) # 场景切换开始信号 # 参数: scene_name - 即将切换到的场景名称 signal scene_change_started(scene_name: String) # ============ 成员变量 ============ # 场景状态 var current_scene_name: String = "" # 当前场景名称 var is_changing_scene: bool = false # 是否正在切换场景 var _next_scene_position: Variant = null # 下一个场景的初始位置 (Vector2 or null) var _next_spawn_name: String = "" # 下一个场景的出生点名称 (String) # 场景路径映射表 # 将场景名称映射到实际的文件路径 # 便于统一管理和修改场景路径 var scene_paths: Dictionary = { "main": "res://scenes/MainScene.tscn", # 主场景 - 游戏入口 "auth": "res://scenes/ui/LoginWindow.tscn", # 认证场景 - 登录窗口 "game": "res://scenes/maps/game_scene.tscn", # 游戏场景 - 主要游戏内容 "battle": "res://scenes/maps/battle_scene.tscn", # 战斗场景 - 战斗系统 "inventory": "res://scenes/ui/InventoryWindow.tscn", # 背包界面 "shop": "res://scenes/ui/ShopWindow.tscn", # 商店界面 "settings": "res://scenes/ui/SettingsWindow.tscn", # 设置界面 "square": "res://scenes/Maps/square.tscn", # 广场地图 "room": "res://scenes/Maps/room.tscn", # 房间地图 "fountain": "res://scenes/Maps/fountain.tscn", # 喷泉地图 "datawhale_home": "res://scenes/Maps/datawhale_home.tscn", # 数据鲸鱼之家 "community": "res://scenes/Maps/community.tscn" # 社区地图 } # ============ 场景切换方法 ============ # 切换到指定场景 # # 参数: # scene_name: String - 要切换到的场景名称(必须在scene_paths中注册) # use_transition: bool - 是否使用过渡效果,默认为true # # 返回值: # bool - 切换是否成功 # # 功能: # - 检查场景切换状态和场景是否存在 # - 显示过渡效果(可选) # - 执行场景切换 # - 更新当前场景状态 # - 发送相关信号 # # 使用示例: # var success = SceneManager.change_scene("main", true) # # 注意事项: # - 场景切换是异步操作 # - 切换过程中会阻止新的切换请求 # - 场景名称必须预先注册 func change_scene(scene_name: String, use_transition: bool = true): # 防止重复切换 if is_changing_scene: push_warning("SceneManager: 场景切换中,忽略新的切换请求") return false # 检查场景是否存在 if not scene_paths.has(scene_name): push_error("SceneManager: 未找到场景 %s" % scene_name) return false var scene_path = scene_paths[scene_name] # 设置切换状态 is_changing_scene = true scene_change_started.emit(scene_name) # 显示过渡效果 if use_transition: await show_transition() # 执行场景切换 var error = get_tree().change_scene_to_file(scene_path) if error != OK: push_error("SceneManager: 场景切换失败 %s -> %s, 错误码: %d" % [current_scene_name, scene_name, error]) is_changing_scene = false return false # 更新状态 current_scene_name = scene_name is_changing_scene = false scene_changed.emit(scene_name) # 隐藏过渡效果 if use_transition: await hide_transition() return true # ============ 查询方法 ============ # 获取当前场景名称 # # 返回值: # String - 当前场景的名称 func get_current_scene_name() -> String: return current_scene_name # ============ 场景位置和出生点管理 ============ # 设置下一个场景的初始位置 # # 参数: # pos: Vector2 - 玩家在下一个场景的初始位置 # # 功能: # - 用于场景切换时传递玩家位置信息 # - 配合 DoorTeleport 等传送机制使用 # # 使用示例: # SceneManager.set_next_scene_position(Vector2(100, 200)) # SceneManager.change_scene("room") func set_next_scene_position(pos: Vector2) -> void: _next_scene_position = pos # 获取并清除下一个场景的初始位置 # # 返回值: # Variant - Vector2 位置或 null(如果未设置) # # 功能: # - 获取预设的场景初始位置 # - 获取后自动清除,避免影响后续场景切换 # # 注意事项: # - 此方法会清除存储的位置,只能获取一次 # - 如果未设置位置,返回 null func get_next_scene_position() -> Variant: var pos = _next_scene_position _next_scene_position = null return pos # 设置下一个场景的出生点名称 # # 参数: # spawn_name: String - 出生点节点的名称 # # 功能: # - 指定玩家在下一个场景应该出现在哪个出生点 # - 配合场景中的 Marker2D 出生点使用 # # 使用示例: # SceneManager.set_next_spawn_name("DoorExit") # SceneManager.change_scene("square") func set_next_spawn_name(spawn_name: String) -> void: _next_spawn_name = spawn_name # 获取并清除下一个场景的出生点名称 # # 返回值: # String - 出生点名称(如果未设置则返回空字符串) # # 功能: # - 获取预设的出生点名称 # - 获取后自动清除,避免影响后续场景切换 # # 注意事项: # - 此方法会清除存储的名称,只能获取一次 # - 如果未设置名称,返回空字符串 func get_next_spawn_name() -> String: var name = _next_spawn_name _next_spawn_name = "" return name # ============ 场景注册方法 ============ # 注册新场景 # # 参数: # scene_name: String - 场景名称(用于切换时引用) # scene_path: String - 场景文件路径 # # 功能: # - 将场景名称和路径添加到映射表 # - 支持运行时动态注册场景 # # 使用示例: # SceneManager.register_scene("boss_battle", "res://scenes/boss/boss_battle.tscn") func register_scene(scene_name: String, scene_path: String): scene_paths[scene_name] = scene_path # ============ 过渡效果方法 ============ # 显示场景切换过渡效果 # # 功能: # - 显示场景切换时的过渡动画 # - 为用户提供视觉反馈 # # 注意事项: # - 这是异步方法,需要await等待完成 # - 当前实现为简单的延时,可扩展为复杂动画 # # TODO: 实现淡入淡出、滑动等过渡效果 func show_transition(): # TODO: 实现场景切换过渡效果(当前仅占位延时) await get_tree().create_timer(0.2).timeout # 隐藏场景切换过渡效果 # # 功能: # - 隐藏场景切换完成后的过渡动画 # - 恢复正常的游戏显示 # # 注意事项: # - 这是异步方法,需要await等待完成 # - 与show_transition()配对使用 # # TODO: 实现与show_transition()对应的隐藏效果 func hide_transition(): # TODO: 隐藏场景切换过渡效果(当前仅占位延时) await get_tree().create_timer(0.2).timeout