diff --git a/addons/gif-importer/importer_plugin.gd b/addons/gif-importer/importer_plugin.gd index ac4f0d0d..e7c52eb6 100644 --- a/addons/gif-importer/importer_plugin.gd +++ b/addons/gif-importer/importer_plugin.gd @@ -97,10 +97,10 @@ func _import(source_file, save_path, options, platform_variants, gen_files): var image = texture.get_image() var image_path = dir_name + str(i) + ".png" image.save_png(image_path) - image.resource_path = image_path - var new_texture = ImageTexture.create_from_image(image) + texture = ImageTexture.create_from_image(image) + texture.take_over_path(image_path) var duration = frames.get_frame_duration("gif", i) - sprite_frames.add_frame(animation_name, new_texture, duration) + sprite_frames.add_frame(animation_name, texture, duration) print_debug("Created images and added to SpriteFrames: ", animation_name) ResourceSaver.save(sprite_frames) return code diff --git a/asset/art/ui/prop遮罩.png b/asset/art/ui/prop/prop遮罩.png similarity index 100% rename from asset/art/ui/prop遮罩.png rename to asset/art/ui/prop/prop遮罩.png diff --git a/asset/art/ui/prop遮罩.png.import b/asset/art/ui/prop/prop遮罩.png.import similarity index 71% rename from asset/art/ui/prop遮罩.png.import rename to asset/art/ui/prop/prop遮罩.png.import index 52749b4f..745ff902 100644 --- a/asset/art/ui/prop遮罩.png.import +++ b/asset/art/ui/prop/prop遮罩.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cgghff16powfg" -path="res://.godot/imported/prop遮罩.png-f0336d91e6b2ddd4060007c0fc87eea0.ctex" +path="res://.godot/imported/prop遮罩.png-85fb17d3ccb28d9d3887ddc81281a85f.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://asset/art/ui/prop遮罩.png" -dest_files=["res://.godot/imported/prop遮罩.png-f0336d91e6b2ddd4060007c0fc87eea0.ctex"] +source_file="res://asset/art/ui/prop/prop遮罩.png" +dest_files=["res://.godot/imported/prop遮罩.png-85fb17d3ccb28d9d3887ddc81281a85f.ctex"] [params] diff --git a/asset/art/ui/prop/遮罩.png b/asset/art/ui/prop/遮罩.png new file mode 100644 index 00000000..58951e30 Binary files /dev/null and b/asset/art/ui/prop/遮罩.png differ diff --git a/asset/art/ui/prop/遮罩.png.import b/asset/art/ui/prop/遮罩.png.import new file mode 100644 index 00000000..caaa4943 --- /dev/null +++ b/asset/art/ui/prop/遮罩.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://f186lvt5y2ql" +path="res://.godot/imported/遮罩.png-dab9f7c60166ce0e17692f077a460bfb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/ui/prop/遮罩.png" +dest_files=["res://.godot/imported/遮罩.png-dab9f7c60166ce0e17692f077a460bfb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/config/animation/frames_display_card.gd b/config/animation/frames_display_card.gd index a5b28af8..6b98640d 100644 --- a/config/animation/frames_display_card.gd +++ b/config/animation/frames_display_card.gd @@ -152,9 +152,10 @@ func _create_mirror(): var flipped_image = mirrored_frame.get_image() as Image flipped_image.flip_x() var flipped_img_path = mirror_dir_path + "/" + id + ".png" - flipped_image.resource_path = flipped_img_path flipped_image.save_png(flipped_img_path) - sprite_frames.add_frame(mirror_mapping, load(flipped_img_path)) + var texture = ImageTexture.create_from_image(flipped_image) + texture.take_over_path(flipped_img_path) + sprite_frames.add_frame(mirror_mapping, texture) sprite_frames.set_animation_speed(mapping_name, frames_per_sec) diff --git a/manager/archive_manager/archive_manager.gd b/manager/archive_manager/archive_manager.gd index 0672df5a..61e8c6b9 100644 --- a/manager/archive_manager/archive_manager.gd +++ b/manager/archive_manager/archive_manager.gd @@ -3,9 +3,8 @@ extends Node signal archive_loaded -static var archive := ( - load("user://data/archives/save0" + GlobalConfig.RES_FILE_FORMAT) as AssembledArchive -) # current archive +static var archive: AssembledArchive +# current archive static var user_root_dir := "user://data/" # must end with "/" static var archive_dir := "user://data/archives/" static var archive_prefix := "save" diff --git a/manager/archive_manager/assembled_archive.gd b/manager/archive_manager/assembled_archive.gd index b5f5efc0..3e02ab0b 100644 --- a/manager/archive_manager/assembled_archive.gd +++ b/manager/archive_manager/assembled_archive.gd @@ -21,10 +21,14 @@ class_name AssembledArchive extends Resource # created time @export var created_time := "2024-12-24 00:00:00" +# 全局参数 +@export var global_data_dict := {} # 不同场景的地面物品状态存档 @export var ground_archives = {} # true 为匿名,false 非匿名 @export var npc_anonymous_states = {} +# 玩家跑步锁定状态 +@export var player_running_locked := true # prop hud 显示道具 @export var prop_inventory: PropInventory @@ -51,3 +55,9 @@ func ground_archive(scene_name := current_scene) -> GroundArchive: return ground_archives[scene_name] +func set_global_entry(property: StringName, value) -> void: + global_data_dict[property] = value + + +func get_global_value(property: StringName) -> Variant: + return global_data_dict.get(property) diff --git a/manager/config_manager/global_config.gd b/manager/config_manager/global_config.gd index 56c306bc..83aaf4e3 100644 --- a/manager/config_manager/global_config.gd +++ b/manager/config_manager/global_config.gd @@ -11,7 +11,8 @@ const CANVAS_LAYER_DIALOG = 23 const CANVAS_LAYER_UI = 22 const CANVAS_LAYER_PROP_INSPECTOR = 21 const CANVAS_LAYER_SETTINGS = 20 -const CANVAS_LAYER_BAG = 11 +const CANVAS_LAYER_BAG = 12 +const CANVAS_LAYER_GROUND_MASK = 11 const CANVAS_LAYER_SHADING = 10 const CANVAS_LAYER_FG = 2 const CANVAS_LAYER_HD_ENTITY = 1 diff --git a/manager/config_manager/global_config_manager.gd b/manager/config_manager/global_config_manager.gd index 1cac5337..053843e4 100644 --- a/manager/config_manager/global_config_manager.gd +++ b/manager/config_manager/global_config_manager.gd @@ -1,9 +1,7 @@ @tool extends Node -static var config := ( - load("user://data/config" + GlobalConfig.RES_FILE_FORMAT) as GlobalConfig -): +static var config: GlobalConfig: set = _set_config var timer = Timer.new() diff --git a/scene/entity/portal.gd b/scene/entity/portal.gd index 77ebe819..8b7f5162 100644 --- a/scene/entity/portal.gd +++ b/scene/entity/portal.gd @@ -72,7 +72,7 @@ func _on_interacted() -> void: # 传送,queue free 导致 sfx 无法播放,使用全局声源 sfx.global_play() if GlobalConfig.DEBUG: - print("传送前往", target_scene, target_portal) + print("传送前往", target_scene, target_portal, " immediately=", immediately) var ground_loader = SceneManager.get_ground_loader() as GroundLoader if ground_loader: ground_loader.transition_to_scene(target_scene, target_portal, immediately) diff --git a/scene/ground/ground.gd b/scene/ground/ground.gd index aa9bb839..90af3e36 100644 --- a/scene/ground/ground.gd +++ b/scene/ground/ground.gd @@ -1,6 +1,7 @@ @tool class_name Ground2D extends Node2D +@export var scene_name := "" @export_group("Player", "player_") @export var player_y_fixed := true @export var player_y := 70: @@ -45,6 +46,11 @@ const FOOTSTEP_AUDIO = { func _ready() -> void: foreground.layer = GlobalConfig.CANVAS_LAYER_FG _reset_player_positon() + # 检查 scene_name 是否合法 + scene_name = scene_name.strip_edges() + if not scene_name or scene_name.length() != 7: + printerr("scene_name is not valid") + return if Engine.is_editor_hint(): return # 如果 debug 模式下不通过 GroundLoader 启动,读取 palyer 位置 diff --git a/scene/ground/ground_loader.gd b/scene/ground/ground_loader.gd index b0c5816a..ea2e29ea 100644 --- a/scene/ground/ground_loader.gd +++ b/scene/ground/ground_loader.gd @@ -8,35 +8,36 @@ class_name GroundLoader extends Node2D @export var debug_reload := false: set(new_val): debug_reload = false - if current_scene and entrance_portal: + if is_node_ready() and current_scene and entrance_portal: transition_to_scene(current_scene, entrance_portal, true) @export var archive_scene := "" @export var archive_portal := "" +@onready var mask_layer := %MaskLayer as CanvasLayer +@onready var mask := %Mask as ColorRect + var first_entered := true var ground: Ground2D +var display_mask_time = 0.0 var scenes_dir = "res://scene/ground/scene/" -var ground_dict = {} +# 场景名字映射到路径 +var ground_scene_path_dict = {} -# 预加载 portal 通往的场景 -var neighbor_scene_cache = {} func _ready() -> void: + mask_layer.layer = GlobalConfig.CANVAS_LAYER_GROUND_MASK + mask.visible = true + mask.color.a = 0.0 + # grounds _read_grounds() - ground = get_node_or_null("Ground") + # ground = get_node_or_null("Ground") # load save if not ignore_archive: _load_save() - if archive_scene and archive_portal: - current_scene = archive_scene - entrance_portal = archive_portal if current_scene and entrance_portal: transition_to_scene(current_scene, entrance_portal, true) - elif ground: - ground.queue_free() - ground = null func _read_grounds() -> void: @@ -47,9 +48,9 @@ func _read_grounds() -> void: 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 + ground_scene_path_dict[c_dir.substr(0, 3) + "_" + s_file.substr(0, 3)] = s_path # # 确保每个 ground 都初始化 archive - # for key in ground_dict.keys(): + # for key in ground_scene_path_dict.keys(): # if GlobalConfig.DEBUG: # print("check ground_archive:", key) # ArchiveManager.archive.ground_archive(key) @@ -61,35 +62,41 @@ func _load_save(): archive_scene = ArchiveManager.archive.current_scene if ArchiveManager.archive.entrance_portal: archive_portal = ArchiveManager.archive.entrance_portal + # 使用 archive 所记录的场景 + if archive_scene and archive_portal: + current_scene = archive_scene + entrance_portal = archive_portal -func transition_to_scene(key: String, portal: String, immediately := false) -> void: - var scene_path = ground_dict[key] +func _toggle_mask(display: bool, _immediately: bool) -> Tween: + var tween = get_tree().create_tween() + if display: + tween.tween_property(mask, "color:a", 1.0, 0.3).set_trans(Tween.TRANS_CUBIC) + display_mask_time = Time.get_ticks_msec() + else: + # var time = Time.get_ticks_msec() + # # 转场至少 0.6s, 除去 0.3s 最后的淡出,需要 0.3s 的等待时间(包含 mask 的淡入) + # if not _immediately: + # var wait_time = max(display_mask_time + 300 - time, 0.0) * 0.001 + # if wait_time: + # tween.tween_interval(wait_time) + tween.tween_property(mask, "color:a", 0.0, 0.3).set_trans(Tween.TRANS_CUBIC) + return tween + + +func transition_to_scene(scene_name: String, portal: String, immediately: bool) -> void: + var scene_path = ground_scene_path_dict.get(scene_name) if scene_path: - var scene = load(scene_path).instantiate() - current_scene = key + current_scene = scene_name entrance_portal = portal # 优先更新 archive,使 ground 可以访问自己的 current_scene 键值 _update_archive() - if immediately: - _do_transition(scene) - # 更新玩家位置 - if first_entered: - _update_player_position() - else: - var tween = create_tween() as 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)) - if player: - tween.tween_callback(func(): player.action_locked = false) - first_entered = false + # 转场效果,在 _load_ground_node 之前播放 + var tween = _toggle_mask(true, immediately) + tween.tween_callback(_do_transition.bind(scene_name)) + tween.tween_callback(_toggle_mask.bind(false, immediately)) else: - print("Scene not found: " + key) + print("Scene not found: " + scene_name) func _update_player_position(): @@ -104,17 +111,30 @@ func _update_player_position(): player.set_facing_direction(ArchiveManager.archive.player_direction) -func _do_transition(scene: Node2D): +func _do_transition(scene_name: String): + # SceneManager.freeze_player(0) + var ground_node = _load_ground_node(scene_name) + if ground == ground_node: + return if ground: # 提前移除,防止命名冲突 remove_child(ground) - ground.queue_free() - ground = scene.get_child(0) - scene.remove_child(ground) - ground.owner = null - scene.queue_free() - add_child(ground) + # 不需要释放,因为会缓存,在 ground_node_cache 中释放 + # ground.queue_free() + # 先设置 ground,再添加到场景中 + # 因为 ground 在 enter_tree 时会用到 SceneManager 的方法 + # 其中间接用到了 GroundLoader 的 ground + ground = ground_node + _add_ground() + # 预先加载邻居场景 + _post_transition() + if GlobalConfig.DEBUG and not Engine.is_editor_hint(): + _watch_scene_update() + + +func _add_ground(): ground.name = "Ground" + add_child(ground) if not Engine.is_editor_hint(): var portal_node = ground.get_node_or_null("DeployLayer/portal_" + entrance_portal) as Node2D if portal_node: @@ -126,8 +146,11 @@ func _do_transition(scene: Node2D): print("move player to portal:", entrance_portal, portal_node.global_position) else: printerr(current_scene + " portal not found: " + entrance_portal) - if GlobalConfig.DEBUG and not Engine.is_editor_hint(): - _watch_scene_update() + # 更新玩家位置 + if first_entered and not Engine.is_editor_hint(): + _update_player_position() + first_entered = false + # SceneManager.release_player() func _update_archive(): @@ -138,13 +161,47 @@ func _update_archive(): archive_portal = entrance_portal +func _load_ground_node(scene_name: String) -> Node2D: + if not ground_scene_path_dict.has(scene_name): + return null + var path = ground_scene_path_dict[scene_name] + var scene = ResourceLoader.load(path) as PackedScene + if scene: + var instance = scene.instantiate() as Node2D + var ground_node = instance.get_child(0) + instance.remove_child(ground_node) + ground_node.owner = null + instance.queue_free() + return ground_node + return null + + +# 读取 portals,预加载邻居场景 +func _post_transition(): + if ground: + var scene_names = [] + var deploy_layer = ground.get_node("DeployLayer") + if deploy_layer: + for node in deploy_layer.get_children(): + var portal = node as Portal2D + if not portal or not portal.target_scene: + continue + if ground_scene_path_dict.has(portal.target_scene): + scene_names.append(portal.target_scene) + if scene_names: + for scene_name in scene_names: + ResourceLoader.load_threaded_request(ground_scene_path_dict[scene_name]) + if GlobalConfig.DEBUG: + print("preload neighbor scenes:", scene_names) + + var update_watcher: Timer var last_modify_time = 0 # DEBUG 时重新加载资源 func _watch_scene_update(): - var scene_path = ground_dict[current_scene] + var scene_path = ground_scene_path_dict[current_scene] if scene_path: last_modify_time = FileAccess.get_modified_time(scene_path) if not update_watcher: diff --git a/scene/ground/ground_loader.tscn b/scene/ground/ground_loader.tscn index b984198c..0abb65ed 100644 --- a/scene/ground/ground_loader.tscn +++ b/scene/ground/ground_loader.tscn @@ -4,3 +4,16 @@ [node name="GroundLoader" type="Node2D"] script = ExtResource("1_6mjre") + +[node name="MaskLayer" type="CanvasLayer" parent="."] +unique_name_in_owner = true + +[node name="Mask" type="ColorRect" parent="MaskLayer"] +unique_name_in_owner = true +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 0) diff --git a/scene/ground/scene/animation_root.gd b/scene/ground/scene/animation_root.gd index 0e652613..ed4ed5cb 100644 --- a/scene/ground/scene/animation_root.gd +++ b/scene/ground/scene/animation_root.gd @@ -73,6 +73,17 @@ func set_data(property: StringName, value: Variant) -> bool: return false +func set_global_entry(property: StringName, value: Variant) -> void: + ArchiveManager.archive.set_global_entry(property, value) + + +func get_global_value(property: StringName, default_value = null) -> Variant: + var val = ArchiveManager.archive.get_global_value(property) + if val == null: + return default_value + return val + + func _get(property: StringName) -> Variant: if property == "oneshot_animation": return oneshot_animation diff --git a/scene/ground/scene/c01/s05_animation.gd b/scene/ground/scene/c01/s05_animation.gd index b4fb39cf..d564cccd 100644 --- a/scene/ground/scene/c01/s05_animation.gd +++ b/scene/ground/scene/c01/s05_animation.gd @@ -15,6 +15,8 @@ func _default_data() -> Dictionary: func _ready() -> void: super._ready() + if Engine.is_editor_hint(): + return func play_intro_dialogue(): @@ -42,6 +44,7 @@ func _on_deploy_layer_ready() -> void: if paper.interacted_times > 0: paper.visible = false paper.enabled = false + right_door.enabled = true else: paper.visible = true paper.enabled = true diff --git a/scene/ground/scene/c01/s05_院长房间.tscn b/scene/ground/scene/c01/s05_院长房间.tscn index 4005fbd0..3497d297 100644 --- a/scene/ground/scene/c01/s05_院长房间.tscn +++ b/scene/ground/scene/c01/s05_院长房间.tscn @@ -206,6 +206,30 @@ tracks/14/keys = { "update": 0, "values": [Vector2(1, 1)] } +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("DeployLayer/oneshot纸片/Sign:display_sign") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("DeployLayer/oneshot纸片/Sign:position") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3, -4)] +} [sub_resource type="Animation" id="Animation_7k2c8"] resource_name = "intro" @@ -546,6 +570,7 @@ metadata/_edit_horizontal_guides_ = [88.0, 122.0] [node name="Ground" parent="." instance=ExtResource("1_ff4yb")] position = Vector2(1, 0) +scene_name = "c01_s05" [node name="AnimationPlayer" parent="Ground" index="0"] libraries = { @@ -566,6 +591,7 @@ position = Vector2(27, 3) position = Vector2(503, 11) texture = ExtResource("4_gdhoy") enabled = false +immediately = false target_scene = "c01_s06" target_portal = "left" default_texture = ExtResource("4_gdhoy") @@ -644,11 +670,10 @@ file = "物品查看.mp3" [node name="Sign" parent="Ground/DeployLayer/oneshot纸片" index="2"] modulate = Color(1, 1, 1, 0) -offset_left = 35.0 -offset_top = -70.0 -offset_right = 35.0 -offset_bottom = -70.0 -display_sign = false +offset_left = 3.0 +offset_top = -4.0 +offset_right = 3.0 +offset_bottom = -4.0 [node name="CollisionShape2D" parent="Ground/DeployLayer/oneshot纸片/Area2D" index="0"] shape = SubResource("RectangleShape2D_5s1ih") diff --git a/scene/ground/scene/c01/s06_animation.gd b/scene/ground/scene/c01/s06_animation.gd index 66ddaabd..e8124393 100644 --- a/scene/ground/scene/c01/s06_animation.gd +++ b/scene/ground/scene/c01/s06_animation.gd @@ -9,6 +9,8 @@ func _default_data() -> Dictionary: func _ready() -> void: super._ready() + if Engine.is_editor_hint(): + return func _on_deploy_layer_ready() -> void: diff --git a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn index 81f5b353..552e6df6 100644 --- a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn +++ b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn @@ -14,6 +14,7 @@ metadata/_edit_horizontal_guides_ = [158.0, 88.0] [node name="Ground" parent="." instance=ExtResource("1_bitx7")] +scene_name = "c01_s06" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_fkfhi") @@ -30,11 +31,13 @@ centered = false [node name="portal_left" parent="Ground/DeployLayer" index="0"] position = Vector2(144, 20) +immediately = false target_scene = "c01_s05" target_portal = "right" [node name="portal_right" parent="Ground/DeployLayer" index="1"] position = Vector2(1886, 28) +immediately = false [node name="男孩" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="2"] position = Vector2(547.5, 0.5) diff --git a/scene/ground/scene/c02/s01_街道.tscn b/scene/ground/scene/c02/s01_街道.tscn index 82e45b19..f3b5ca31 100644 --- a/scene/ground/scene/c02/s01_街道.tscn +++ b/scene/ground/scene/c02/s01_街道.tscn @@ -9,6 +9,7 @@ [node name="S01" type="Node2D"] [node name="Ground" parent="." instance=ExtResource("1_gdcov")] +scene_name = "c02_s01" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_uuwn3") @@ -38,7 +39,7 @@ dialogue = "c02" position = Vector2(135, 56) [node name="MainPlayer" parent="Ground" index="5"] -position = Vector2(78, 40) +position = Vector2(78, 88) [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] texture = null diff --git a/scene/ground/scene/c02/s02_animation.gd b/scene/ground/scene/c02/s02_animation.gd index 0cdc2957..1b15eddc 100644 --- a/scene/ground/scene/c02/s02_animation.gd +++ b/scene/ground/scene/c02/s02_animation.gd @@ -11,6 +11,8 @@ func _default_data() -> Dictionary: func _ready() -> void: super._ready() + if Engine.is_editor_hint(): + return func _on_deploy_layer_ready() -> void: diff --git a/scene/ground/scene/c02/s02_走道.tscn b/scene/ground/scene/c02/s02_走道.tscn index 4d1989d9..044dc021 100644 --- a/scene/ground/scene/c02/s02_走道.tscn +++ b/scene/ground/scene/c02/s02_走道.tscn @@ -43,6 +43,7 @@ size = Vector2(35, 70) [node name="S02" type="Node2D"] [node name="Ground" parent="." instance=ExtResource("1_wrr6r")] +scene_name = "c02_s02" [node name="AnimationPlayer" parent="Ground" index="0"] libraries = { diff --git a/scene/ground/scene/c02/s03_animation.gd b/scene/ground/scene/c02/s03_animation.gd index 48a3c043..f107c44a 100644 --- a/scene/ground/scene/c02/s03_animation.gd +++ b/scene/ground/scene/c02/s03_animation.gd @@ -9,6 +9,8 @@ func _default_data() -> Dictionary: func _ready() -> void: super._ready() + if Engine.is_editor_hint(): + return func _on_deploy_layer_ready() -> void: diff --git a/scene/ground/scene/c02/s03_院子切换.tscn b/scene/ground/scene/c02/s03_院子切换.tscn index 49bd6570..6a0332f7 100644 --- a/scene/ground/scene/c02/s03_院子切换.tscn +++ b/scene/ground/scene/c02/s03_院子切换.tscn @@ -23,6 +23,7 @@ size = Vector2(40, 70) [node name="S03" type="Node2D"] [node name="Ground" parent="." instance=ExtResource("1_lheeb")] +scene_name = "c02_s03" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_l2oec") @@ -41,7 +42,7 @@ position = Vector2(629, 2) [node name="Npc" parent="Ground/DeployLayer" index="2" instance=ExtResource("2_r5smg")] position = Vector2(465, 23) -frame_progress = 0.799802 +frame_progress = 0.514003 character_name = "张胖子" dialogue_title = "张胖子_01" @@ -72,7 +73,7 @@ ambient_light_energy = 2.0 position = Vector2(1120, 5) [node name="MainPlayer" parent="Ground" index="5"] -position = Vector2(25, 40) +position = Vector2(25, 88) [node name="BGParallaxLayer" parent="Ground/ParallaxForeground" index="0"] use_parent_material = true diff --git a/scene/ground/scene/template_animation.gd b/scene/ground/scene/template_animation.gd index 66ddaabd..e8124393 100644 --- a/scene/ground/scene/template_animation.gd +++ b/scene/ground/scene/template_animation.gd @@ -9,6 +9,8 @@ func _default_data() -> Dictionary: func _ready() -> void: super._ready() + if Engine.is_editor_hint(): + return func _on_deploy_layer_ready() -> void: diff --git a/scene/player/main_player.gd b/scene/player/main_player.gd index 7c4ba989..325b7217 100644 --- a/scene/player/main_player.gd +++ b/scene/player/main_player.gd @@ -62,6 +62,17 @@ func _ready() -> void: footstep_timer.timeout.connect(_on_footstep_timer_timeout) footstep_timer.stop() # SceneManager.focus_player(self) + _check_character_status() + + +func _enter_tree() -> void: + if is_node_ready(): + _check_character_status() + + +func _check_character_status(): + # 检查角色锁定状态 + running_locked = ArchiveManager.archive.player_running_locked func _on_footstep_timer_timeout(): diff --git a/scene/prop/prop_inspector.tscn b/scene/prop/prop_inspector.tscn index 6a0bf496..936041c6 100644 --- a/scene/prop/prop_inspector.tscn +++ b/scene/prop/prop_inspector.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=5 format=3 uid="uid://cekhj65axie0p"] [ext_resource type="Script" path="res://scene/prop/prop_inspector.gd" id="1_2wpwe"] +[ext_resource type="Texture2D" uid="uid://f186lvt5y2ql" path="res://asset/art/ui/prop/遮罩.png" id="2_j83lq"] [ext_resource type="Texture2D" uid="uid://cvgw2mxrlr6io" path="res://asset/art/scene/c02/s02_走道/ux_进门鼠疫海报yz.png" id="2_wr575"] -[ext_resource type="Texture2D" uid="uid://cgghff16powfg" path="res://asset/art/ui/prop遮罩.png" id="3_uf004"] [sub_resource type="LabelSettings" id="LabelSettings_5qe7a"] line_spacing = 1.0 @@ -25,7 +25,7 @@ grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 4 mouse_filter = 2 -texture = ExtResource("3_uf004") +texture = ExtResource("2_j83lq") [node name="CenterContainer" type="CenterContainer" parent="."] anchors_preset = 8 @@ -108,6 +108,6 @@ unique_name_in_owner = true modulate = Color(1, 1, 1, 0) layout_mode = 2 size_flags_horizontal = 4 -text = "Q: 退出 E: 阅读" +text = "Q: ui_退出 E: ui_阅读" horizontal_alignment = 1 vertical_alignment = 1 diff --git a/util/lru.gd b/util/lru.gd new file mode 100644 index 00000000..351075d1 --- /dev/null +++ b/util/lru.gd @@ -0,0 +1,49 @@ +@tool +class_name LRU extends RefCounted + +# LRU 算法 +var cache_size = 1 +# keys. 新的在后面,旧的在前面 +var lru_list = [] +# key -> value +var cache = {} +var cache_mutex = Mutex.new() + + +func _init(size := 8) -> void: + cache_size = size + + +func _get(key: Variant) -> Variant: + var v = null + cache_mutex.lock() + if cache.has(key): + lru_list.erase(key) + lru_list.append(key) + v = cache[key] + cache_mutex.unlock() + return v + + +func _set(key: StringName, value: Variant) -> bool: + cache_mutex.lock() + if cache.has(key): + lru_list.erase(key) + if cache[key] != value: + _release_value(cache[key]) + cache[key] = value + lru_list.append(key) + if lru_list.size() > cache_size: + var k = lru_list.pop_front() + _release_value(cache[k]) + cache.erase(k) + cache_mutex.unlock() + return true + + +func _release_value(v: Variant) -> void: + if v is Node: + if not v.is_inside_tree() and is_instance_valid(v): + v.queue_free() + elif not v is RefCounted: + v.free()