@tool class_name GroundLoader extends Node2D @export var current_scene := "c02_s01" @export var entrance_portal := "left" var ground: Node2D var scenes_dir = "res://scene/ground/scene/" var ground_dict = {} func _ready() -> void: _load_save() _read_grounds() if current_scene and entrance_portal: transition_to_scene(current_scene, entrance_portal, true) func _load_save(): if ArchiveManager.archive: if ArchiveManager.archive.current_scene: current_scene = ArchiveManager.archive.current_scene if ArchiveManager.archive.entrance_portal: entrance_portal = ArchiveManager.archive.entrance_portal func _read_grounds(): var dir = DirAccess.open(scenes_dir) for c_dir in dir.get_directories(): var c_path = scenes_dir + c_dir + "/" for s_file in DirAccess.open(c_path).get_files(): if s_file.ends_with(".tscn"): var s_path = c_path + s_file ground_dict[c_dir.substr(0, 3) + "_" + s_file.substr(0, 3)] = s_path func play_footstep_sound() -> void: if ground and ground.is_visible_in_tree(): ground.play_footstep_sound() func transition_to_scene(key: String, portal: String, load_save := false) -> void: var scene_path = ground_dict[key] if scene_path: var scene = load(scene_path).instantiate() current_scene = key entrance_portal = portal if load_save: _do_transition(scene) # 更新玩家位置 _update_player_position() else: var tween = create_tween() var player = SceneManager.get_player() as MainPlayer if player: player.action_locked = true #TODO 转场效果 # tween.tween_interval(0.2) tween.tween_callback(_do_transition.bind(scene)) tween.tween_callback(func(): player.action_locked = false) else: print("Scene not found: " + key) func _update_player_position(): var player = SceneManager.get_player() as MainPlayer if player and ArchiveManager.archive: # if GlobalConfig.DEBUG: # print("update player position", ArchiveManager.archive.player_global_position) player.global_position = ArchiveManager.archive.player_global_position player.set_facing_direction(ArchiveManager.archive.player_direction) func _do_transition(scene: Node2D): if ground: ground.queue_free() # 提前移除,防止命名冲突 remove_child(ground) ground = scene.get_child(0) scene.remove_child(ground) scene.queue_free() add_child(ground) ground.name = "Ground" _set_camera_and_player_boundary() _update_archive() var portal_node = get_node_or_null("./Ground/DeployLayer/portal_" + entrance_portal) as Node2D if portal_node: print("set player to portal:", entrance_portal) var player = SceneManager.get_player() if player: player.global_position.x = portal_node.global_position.x func _set_camera_and_player_boundary(): var bg = ground.get_node("BGSprite2D") if bg.texture: SceneManager.set_camera_boundary(bg.texture.get_size()) SceneManager.set_player_boundary(bg.texture.get_size()) func _update_archive(): ArchiveManager.archive.current_scene = current_scene ArchiveManager.archive.entrance_portal = entrance_portal