forked from datawhale/whale-town-front
247 lines
7.4 KiB
GDScript
247 lines
7.4 KiB
GDScript
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
|