## SceneManager — 场景路由 + 黑幕淡入淡出(Autoload: SceneManager) ## 所有场景跳转必须经过此单例,保证转场动画一致。 extends Node const FADE_DURATION: float = 0.35 ## 下一次加载游戏场景时的启动模式 ## "new"=新游戏 "continue"=读档继续 "endless"=无尽模式 var start_mode: String = "new" var is_transitioning: bool = false var _overlay: ColorRect = null var _tween: Tween = null # 场景路径注册表 const SCENES: Dictionary = { "splash": "res://scenes/ui/splash.tscn", "main_menu": "res://scenes/ui/main_menu.tscn", "game": "res://scenes/main/combat_s2.tscn", } func _ready() -> void: # 转场需在暂停态下也能运行(从暂停菜单返回主菜单等) process_mode = Node.PROCESS_MODE_ALWAYS # 全屏黑幕覆盖层(始终在最顶层) var cl := CanvasLayer.new() cl.layer = 127 add_child(cl) _overlay = ColorRect.new() _overlay.color = Color.BLACK _overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE _overlay.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) cl.add_child(_overlay) _overlay.modulate.a = 1.0 # 从黑屏开始,首屏淡入 func _fade_in(on_done: Callable = Callable()) -> void: if _tween: _tween.kill() _tween = create_tween() _tween.tween_property(_overlay, "modulate:a", 0.0, FADE_DURATION) if not on_done.is_null(): _tween.tween_callback(on_done) func _fade_out(on_done: Callable = Callable()) -> void: if _tween: _tween.kill() _tween = create_tween() _tween.tween_property(_overlay, "modulate:a", 1.0, FADE_DURATION) if not on_done.is_null(): _tween.tween_callback(on_done) ## 通用跳转(不建议直接调用,优先用下方语义方法) func goto(scene_id: String) -> void: if is_transitioning: return is_transitioning = true _fade_out(func(): get_tree().change_scene_to_file(SCENES[scene_id]) call_deferred("_after_scene_load") ) func _after_scene_load() -> void: _fade_in(func(): is_transitioning = false) ## ── 语义跳转方法 ──────────────────────────────────────────── func goto_splash() -> void: goto("splash") func goto_main_menu() -> void: goto("main_menu") ## 启动新游戏(从头开始) func start_new_game() -> void: start_mode = "new" goto("game") ## 继续上局存档 func continue_game() -> void: start_mode = "continue" goto("game") ## 初始淡入(场景 _ready 调用)。经 goto 进入时由 _after_scene_load 独占淡入, ## 此处跳过以免 kill 掉带"复位 is_transitioning"回调的转场 Tween(仅单独启动场景时淡入)。 func fade_in_first() -> void: if is_transitioning: return _fade_in() ## 当前是否有可继续的存档 func has_save() -> bool: return FileAccess.file_exists(ProfileManager.PATH_A) or \ FileAccess.file_exists(ProfileManager.PATH_B)