diff --git a/asset/art/gif/c01_孤儿院围墙/c01_孤儿院围墙_frames.tres b/asset/art/gif/c01_孤儿院围墙/c01_孤儿院围墙_frames.tres index 43f50475..30cc61d7 100644 --- a/asset/art/gif/c01_孤儿院围墙/c01_孤儿院围墙_frames.tres +++ b/asset/art/gif/c01_孤儿院围墙/c01_孤儿院围墙_frames.tres @@ -825,7 +825,7 @@ animations = [{ "duration": 3.0, "texture": ExtResource("115_l68hn") }], -"loop": true, +"loop": false, "name": &"桌椅正常", "speed": 30.0 }, { diff --git a/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/0.png.import b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/0.png.import new file mode 100644 index 00000000..25587e50 --- /dev/null +++ b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/0.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4t23h3srxw5q" +path="res://.godot/imported/0.png-60280c8fd45952e7df9b96e291860ffe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/0.png" +dest_files=["res://.godot/imported/0.png-60280c8fd45952e7df9b96e291860ffe.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/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/1.png.import b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/1.png.import new file mode 100644 index 00000000..8138f8ce --- /dev/null +++ b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/1.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://di0yxge1q55q4" +path="res://.godot/imported/1.png-d01feb083416d9768ff23ec7d63ba562.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/1.png" +dest_files=["res://.godot/imported/1.png-d01feb083416d9768ff23ec7d63ba562.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/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/2.png.import b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/2.png.import new file mode 100644 index 00000000..407a73ef --- /dev/null +++ b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://h871c7r6g2t5" +path="res://.godot/imported/2.png-b6372c9fb49112edff670bf4484c2373.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/2.png" +dest_files=["res://.godot/imported/2.png-b6372c9fb49112edff670bf4484c2373.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/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/3.png.import b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/3.png.import new file mode 100644 index 00000000..158a1028 --- /dev/null +++ b/asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bvmbm3y620tm5" +path="res://.godot/imported/3.png-8ffb7363131c44fd5f1a8e2d740ec584.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/gif/c03_小小小蝶上楼道/小小小蝶动画(跑)/3.png" +dest_files=["res://.godot/imported/3.png-8ffb7363131c44fd5f1a8e2d740ec584.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/asset/dialogue/item_description.csv b/asset/dialogue/item_description.csv index 39c1c59b..d94371cb 100644 --- a/asset/dialogue/item_description.csv +++ b/asset/dialogue/item_description.csv @@ -195,3 +195,8 @@ c02_霸凌救小蝉开始,啊!我得想办法帮帮她...,,,,, c02_点火前阻止右移,没时间浪费了!想想办法救出小蝉...,,,,, c02_看到小蝉上楼,?!,,,,, c02_看到杂物堆消失,楼梯口的杂物消失了...,,,,, +c02_demo感谢试玩,感谢试玩,,,,, +c02_demo公告,以上是《衔蝶》demo的全部内容啦,感谢你抽出宝贵的时间体验我们的游戏!
试玩虽然结束,但吕萍的旅程才刚刚开始,后面的故事将更加精彩!你在游戏中探索的每一步都是对我们的鼓励和支持!
在游戏上线前,我们将继续优化游戏内容,完善和打磨游戏设计、叙事流程,音效、画面表现等。
最后,欢迎你对《衔蝶》的试玩提出反馈,这对我们非常重要!期待与你的下次相遇,再见!,,,,,"The above is all the content of the ""Butterfly Carrying"" demo. Thank you for taking the precious time to experience our game!
Although the trial play has ended, Lu Ping's journey has just begun. The story that follows will be even more exciting! Every step you take in the game is an encouragement and support for us!
Before the game is launched, we will continue to optimize the game content, refine and polish the game design, narrative process, sound effects, visual presentation, etc.
Finally, we welcome your feedback on the trial play of ""Butterfly Carrying"". This is very important to us! Looking forward to our next meeting. Goodbye!" +c03_s01_走近3012,3012号房,应该就是我小时候住的地方,,,,, +c03_s01_门口看病牌子,义诊,,,,, +c03_s01_偷听完3012,......,,,,, diff --git a/asset/dialogue/item_description.dialogue b/asset/dialogue/item_description.dialogue index 46e3b1e3..da92b140 100644 --- a/asset/dialogue/item_description.dialogue +++ b/asset/dialogue/item_description.dialogue @@ -260,10 +260,16 @@ # 结尾 ?! [ID:c02_看到小蝉上楼] 楼梯口的杂物消失了... [ID:c02_看到杂物堆消失] +感谢试玩 [ID:c02_demo感谢试玩] +以上是《衔蝶》demo的全部内容啦,感谢你抽出宝贵的时间体验我们的游戏!
试玩虽然结束,但吕萍的旅程才刚刚开始,后面的故事将更加精彩!你在游戏中探索的每一步都是对我们的鼓励和支持!
在游戏上线前,我们将继续优化游戏内容,完善和打磨游戏设计、叙事流程,音效、画面表现等。
最后,欢迎你对《衔蝶》的试玩提出反馈,这对我们非常重要!期待与你的下次相遇,再见! [ID:c02_demo公告] => END ~ Notes_c03 -# s01 +# s01 三楼 +3012号房,应该就是我小时候住的地方 [ID:c03_s01_走近3012] +义诊 [ID:c03_s01_门口看病牌子] +...... [ID:c03_s01_偷听完3012] +#奇怪...里面应该有人在的...
要不先去小蝉家看看吧 # s02 # s03 # s04 diff --git a/manager/event_manager/event2d.gd b/manager/event_manager/event2d.gd index 9c3ecdcb..9a75366b 100644 --- a/manager/event_manager/event2d.gd +++ b/manager/event_manager/event2d.gd @@ -69,7 +69,7 @@ func _on_stage_updated(): ###### TOOL BUTTON var script_template = preload("uid://bmxsei74o3pyw") as Script - +var script_root_dir = "res://scene/ground/script/" func _create_script(): var script = script_template.duplicate(true) as Script @@ -80,11 +80,12 @@ func _create_script(): printerr("[Event2D] _create_script Ground2D not found.") return var chapter = ground.scene_name.substr(0, 3) - if len(chapter) != 3: - printerr("[Event2D] _create_script chapter name error: %s" % ground.scene_name) + var section = ground.scene_name.substr(4, 3) + if len(chapter) != 3 or len(section) != 3: + printerr("[Event2D] ground scene_name error: %s" % ground.scene_name) return - var file_name = name.to_snake_case() + ".gd" - var path = "res://scene/ground/script/" + chapter + "/" + file_name + var file_name = section + "_" + name.to_snake_case() + ".gd" + var path = script_root_dir + chapter + "/" + file_name if FileAccess.file_exists(path): print("file exists, reattach the script to node: %s" % path) set_script(load(path)) diff --git a/manager/event_manager/event_binder.gd b/manager/event_manager/event_binder.gd new file mode 100644 index 00000000..64aa86b5 --- /dev/null +++ b/manager/event_manager/event_binder.gd @@ -0,0 +1,108 @@ +@tool +class_name EventBinder extends Node + +@export_group("Updater", "updater") +@export var updater_event := &"" +@export_enum("enabler", "disabler", "shower", "hider") var updater_mode := "enabler" +# 仅对 canvas item 生效; <=0 时无 ease +@export var updater_ease_duration := 1.0 +@export_enum("include", "exclude") var updater_stage_mode := "include" +@export var updater_stages: Array[int] = [1] + +@export_group("Trigger", "trigger") +@export var trigger_event := &"" +@export_tool_button("AutoDetectMode") var trigger_auto_detect_mode := _auto_detect_mode +@export_enum("none", "interacted", "triggered", "played") var trigger_mode := "none" +@export_range(0, 10000, 1) var trigger_stage := 1 +@export var trigger_set_stage_if_greater := true + +var _local_enable_event_stage := 0 + + +func _ready() -> void: + if Engine.is_editor_hint(): + return + var parent = get_parent() + if not updater_event.is_empty(): + if not parent: + printerr("[EventBinder] bind_enable is true but parent is null. path: %s" % get_path()) + return + _local_enable_event_stage = EventManager.get_stage(updater_event) + _update_binding_state(_local_enable_event_stage) + EventManager.stage_updated.connect(_on_global_stage_updated) + if not trigger_event.is_empty(): + # connect trigger_mode signal + if trigger_mode == "interacted": + parent.interacted.connect(_on_happened) + elif trigger_mode == "triggered": + parent.triggered.connect(_on_happened) + elif trigger_mode == "played": + parent.played.connect(_on_happened) + + +func _on_happened() -> void: + if trigger_set_stage_if_greater: + var updated = EventManager.set_stage_if_greater(trigger_event, trigger_stage) + if not updated: + print( + ( + "[EventBinder] _on_happened not updated, event: %s, stage: %s" + % [trigger_event, EventManager.get_stage(trigger_event)] + ) + ) + else: + EventManager.set_stage(trigger_event, trigger_stage) + + +func _on_global_stage_updated(e: StringName, s: int): + if e == updater_event: + _local_enable_event_stage = s + _update_binding_state(s) + + +func _update_binding_state(stage: int): + var parent = get_parent() + if not parent: + printerr("[EventBinder] _update_updater_visibility parent is null. path: %s" % get_path()) + return + # check stage in updater_stages + var updater_status = false + if updater_stage_mode == "exclude": + updater_status = not stage in updater_stages + elif updater_stage_mode == "include": + updater_status = stage in updater_stages + # check updater_mode + if updater_mode == "enabler": + parent.enabled = updater_status + elif updater_mode == "disabler": + parent.enabled = not updater_status + elif updater_mode == "shower": + _toggle_parent_visibility_with_ease(parent, updater_status) + elif updater_mode == "hider": + _toggle_parent_visibility_with_ease(parent, not updater_status) + + +func _toggle_parent_visibility_with_ease(parent, show: bool): + if parent is CanvasItem: + parent.visible = true + parent.modulate.a = 0.0 if show else 1.0 + var target_a = 1.0 if show else 0.0 + var tween = create_tween() + tween.tween_property(parent, "modulate:a", target_a, updater_ease_duration) + if not show: + tween.tween_callback(parent.hide) + + +func _auto_detect_mode(): + # TODO 统一interacted played picked + var parent = get_parent() + if not parent: + printerr("[EventBinder] _auto_detect_mode parent is null. path: %s" % get_path()) + if parent.has_signal("interacted"): + trigger_mode = "interacted" + elif parent.has_signal("triggered"): + trigger_mode = "triggered" + elif parent.has_signal("played"): + trigger_mode = "played" + else: + printerr("[EventBinder] _auto_detect_mode cannot detect trigger mode. path:", get_path()) diff --git a/manager/event_manager/event_binder.gd.uid b/manager/event_manager/event_binder.gd.uid new file mode 100644 index 00000000..c7fa9947 --- /dev/null +++ b/manager/event_manager/event_binder.gd.uid @@ -0,0 +1 @@ +uid://0wjaho6qkg6s diff --git a/scene/character/main_player.gd b/scene/character/main_player.gd index f848d5a7..c9bfd2d7 100644 --- a/scene/character/main_player.gd +++ b/scene/character/main_player.gd @@ -392,8 +392,10 @@ func walk_to(global_pos: Vector2) -> Tween: tween.tween_callback(_after_walk_to) return tween + var paused_animation_name := "" + func toggle_pause_state(pause := true) -> void: if pause: sprite.pause() @@ -407,3 +409,9 @@ func _after_walk_to() -> void: if GlobalConfig.DEBUG: print("walk_to end. unlock player") SceneManager.unlock_player() + + +func update_x_with_camera_followed(global_position_x: float) -> void: + global_position.x = global_position_x + if camera_marker: + camera_marker.reset_position_immediately() diff --git a/scene/entity/closeup.gd b/scene/entity/closeup.gd index e540839b..852ec6e3 100644 --- a/scene/entity/closeup.gd +++ b/scene/entity/closeup.gd @@ -8,6 +8,8 @@ signal exit(arg) @export var packed_scene: PackedScene @export var quit_closeup_on_escape := true +@export_tool_button("新建特写场景") var create_closeup_scene = _create_scene_with_script + var current_child: Node @@ -63,3 +65,46 @@ func _unhandled_input(event: InputEvent) -> void: # 在有特写界面时,阻塞 interact 输入 elif event.is_action_pressed("interact"): get_viewport().set_input_as_handled() + + +###### TOOL BUTTON + +var scene_root_dir +var script_template = preload("uid://dnrql1t0j6v8i") as Script +var scene_template = preload("uid://beifpduqgoyvo") as PackedScene +var script_root_dir = "res://scene/ground/script/" + + +func _create_scene_with_script(): + if packed_scene: + print_rich("[color=orange][Closeup2D] packed_scene already exists, skip creating new scene and script.") + return + var script = script_template.duplicate(true) as Script + var new_packed_scene = PackedScene.new() + var ground = get_node("..") + while ground and not ground is Ground2D: + ground = ground.get_node("..") + if not ground: + printerr("[Closeup2D] _create_script Ground2D not found.") + return + var chapter = ground.scene_name.substr(0, 3) + var section = ground.scene_name.substr(4, 3) + if len(chapter) != 3 or len(section) != 3: + printerr("[Closeup2D] ground scene_name error: %s" % ground.scene_name) + return + var base_file_name = script_root_dir + chapter + "/" + section + "_" + name.to_snake_case() + script.resource_path = base_file_name + ".gd" + new_packed_scene.resource_path = base_file_name + ".tscn" + ResourceSaver.save(script, script.resource_path) + var scene_node = scene_template.instantiate() + scene_node.set_script(script) + scene_node.name = name + new_packed_scene.pack(scene_node) + ResourceSaver.save(new_packed_scene) + packed_scene = load(new_packed_scene.resource_path) + print( + ( + "[Closeup2D] Script and scene created: %s, %s" + % [script.resource_path, new_packed_scene.resource_path] + ) + ) diff --git a/scene/ground/script/c02/通用特写脚本.gd b/scene/entity/closeup_template.gd similarity index 70% rename from scene/ground/script/c02/通用特写脚本.gd rename to scene/entity/closeup_template.gd index 5b9c9b50..728f7339 100644 --- a/scene/ground/script/c02/通用特写脚本.gd +++ b/scene/entity/closeup_template.gd @@ -1,5 +1,7 @@ extends CanvasLayer +@onready var bg = $BG as TextureRect + func _ready() -> void: layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME diff --git a/scene/ground/script/c02/通用特写脚本.gd.uid b/scene/entity/closeup_template.gd.uid similarity index 100% rename from scene/ground/script/c02/通用特写脚本.gd.uid rename to scene/entity/closeup_template.gd.uid diff --git a/scene/entity/closeup_template.tscn b/scene/entity/closeup_template.tscn new file mode 100644 index 00000000..e845c56d --- /dev/null +++ b/scene/entity/closeup_template.tscn @@ -0,0 +1,58 @@ +[gd_scene load_steps=6 format=3 uid="uid://beifpduqgoyvo"] + +[ext_resource type="Script" uid="uid://dnrql1t0j6v8i" path="res://scene/entity/closeup_template.gd" id="1_27asw"] +[ext_resource type="Texture2D" uid="uid://cbql1i4hblmt1" path="res://asset/art/ui/遮罩/inspect特写通用遮罩.png" id="3_0srdb"] +[ext_resource type="PackedScene" uid="uid://dmysq4sxx8iqh" path="res://scene/entity/ux/content_inspector.tscn" id="4_qivto"] +[ext_resource type="Texture2D" uid="uid://f186lvt5y2ql" path="res://asset/art/ui/遮罩/inspect背景遮罩.png" id="5_gd3hs"] +[ext_resource type="Script" uid="uid://dpocj5al0rvai" path="res://ui/text_helper.gd" id="5_ik70a"] + +[node name="Closeup" type="CanvasLayer"] +script = ExtResource("1_27asw") + +[node name="BG" type="TextureRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 0 + +[node name="遮罩" type="TextureRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = ExtResource("3_0srdb") + +[node name="ContentInspector" parent="." instance=ExtResource("4_qivto")] +mouse_filter = 2 + +[node name="遮罩" type="TextureRect" parent="ContentInspector"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = ExtResource("5_gd3hs") + +[node name="Label" type="Label" parent="ContentInspector/遮罩"] +custom_minimum_size = Vector2(180, 0) +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -60.0 +offset_top = -15.5 +offset_right = 60.0 +offset_bottom = 15.5 +grow_horizontal = 2 +grow_vertical = 2 +vertical_alignment = 1 +autowrap_mode = 3 +script = ExtResource("5_ik70a") diff --git a/scene/entity/interactable.gd b/scene/entity/interactable.gd index b0420c2f..3d055d2b 100644 --- a/scene/entity/interactable.gd +++ b/scene/entity/interactable.gd @@ -199,7 +199,8 @@ func _get_property_list() -> Array[Dictionary]: var current_line = item_config_res.lines[id] while current_line: if current_line.has("translation_key"): - items.append(current_line.translation_key) + if not current_line.translation_key.ends_with("_说明"): + items.append(current_line.translation_key) if not current_line.has("next_id") or current_line.next_id == "end": break current_line = item_config_res.lines[current_line.next_id] diff --git a/scene/entity/ux/sign_snapper.gd b/scene/entity/ux/sign_snapper.gd index 5668a340..e54306f1 100644 --- a/scene/entity/ux/sign_snapper.gd +++ b/scene/entity/ux/sign_snapper.gd @@ -18,7 +18,7 @@ signal arrived @export var action_on_arrived := 3 @export_tool_button("debug 检查玩家触发位置") var debug_check_player_pos = _debug_check_player_pos -var detacted_sign: Sign +var detected_sign: Sign # arrived 延时: delay_arrived-arrived static var delay_arrived := 0.0 @@ -31,16 +31,16 @@ func _ready(): return for c in get_parent().get_children(): if c is Sign: - detacted_sign = c + detected_sign = c break - if not detacted_sign and Engine.is_editor_hint(): + if not detected_sign and Engine.is_editor_hint(): printerr("SignSnapper must have a Sign sibling node!") if not Engine.is_editor_hint(): - detacted_sign.interacted.connect(_on_interacted) + detected_sign.interacted.connect(_on_interacted) func _on_interacted(): - if not detacted_sign or not enabled: + if not detected_sign or not enabled: return var player = SceneManager.get_player() var target_pos = global_position diff --git a/scene/ground/camera/camera_focus_marker.gd b/scene/ground/camera/camera_focus_marker.gd index 07e9f041..5e9cb7dc 100644 --- a/scene/ground/camera/camera_focus_marker.gd +++ b/scene/ground/camera/camera_focus_marker.gd @@ -2,19 +2,14 @@ class_name CameraFocusMarker extends Camera2D @export var focusing_node: Node2D @export var force_offset := Vector2.ZERO -@export_group("Status") -@export var lock_horizontal = true +# @export_group("Status") +# @export var lock_horizontal = true @export_group("Config") @export var half_screen_size := Vector2(564, 240) / 2.0 @export var shaded_height := 38 @export_group("Shake", "shake_") @export var shake_strength := 0.0 @export var shake_recovery_speed := 4.0 -# @export_group("Limit", "limit_") -# @export var limit_left := 0.0 -# @export var limit_right := 564.0 -# @export var limit_top := 0 -# @export var limit_bottom := 316.0 @export var zoom_ratio := 1.0 var speed := 2.0 @@ -38,7 +33,8 @@ func shake_camera(strength := 6.0, recovery_speed := 2.0, ignore_boundary := tru func reset_position_immediately(): if focusing_node: - global_position = focusing_node.global_position + _tweeked_position + force_offset + progressing_position = focusing_node.global_position + _tweeked_position + force_offset + global_position = progressing_position print("CameraFocusMarker reset_position_immediately to:", global_position) @@ -48,11 +44,11 @@ func tweak_position(velocity, facing_direction): var delta = ideal_x - current_x if abs(delta) > 10.0: _tweeked_position.x = move_toward(current_x, ideal_x, speed * 2.0) - if lock_horizontal: - global_position.y = 0 - _tweeked_position.y = 0 - else: - _tweeked_position.y = facing_direction.y * abs(velocity.y) * 0.2 + # if lock_horizontal: + # global_position.y = 0 + # _tweeked_position.y = 0 + # else: + # _tweeked_position.y = facing_direction.y * abs(velocity.y) * 0.2 # 处理过程的当下理想位置 diff --git a/scene/ground/camera/camera_focus_marker.tscn b/scene/ground/camera/camera_focus_marker.tscn index 1c73f089..15a0f375 100644 --- a/scene/ground/camera/camera_focus_marker.tscn +++ b/scene/ground/camera/camera_focus_marker.tscn @@ -4,4 +4,9 @@ [node name="CameraFocusMarker" type="Camera2D"] process_mode = 1 +limit_left = -1000 +limit_top = -1000 +limit_right = 20000 +limit_bottom = 1000 +editor_draw_limits = true script = ExtResource("1_7t4e6") diff --git a/scene/ground/ground.gd b/scene/ground/ground.gd index b1007b82..9192ca0a 100644 --- a/scene/ground/ground.gd +++ b/scene/ground/ground.gd @@ -79,12 +79,11 @@ func _ready() -> void: scene_name = scene_name.strip_edges() if get_parent().name.begins_with("S") and (not scene_name or scene_name.length() != 7): printerr("scene_name is not valid") + _set_camera_and_player_boundary() if Engine.is_editor_hint(): return - SceneManager.toggle_hud_display(display_hud) # 隐藏 player_line player_line.visible = false - _set_camera_and_player_boundary() _load_footstep_audio() # marker 默认就在 foucs player 状态 # camera_focus_marker.focus_node(player) @@ -92,6 +91,7 @@ func _ready() -> void: # %ColorRectBottom.visible = true # 如果 debug 模式下不通过 GroundLoader 启动,则插入到 main 以下 _setup_player_light() + SceneManager.toggle_hud_display(display_hud) func _restart_from_main(): @@ -133,7 +133,7 @@ func _set_camera_and_player_boundary(): # set current_boarder by bg size var camera_rect = Rect2(0, -158, 564, 316) var player_rect = Rect2(0, -158, 564, 316) - if bg_sprite.texture and not Engine.is_editor_hint(): + if bg_sprite.texture: var size = bg_sprite.texture.get_size() * bg_sprite.scale # camera rect var camera_size = size diff --git a/scene/ground/scene/animation_root.gd b/scene/ground/scene/animation_root.gd index 2337dfcc..acf97694 100644 --- a/scene/ground/scene/animation_root.gd +++ b/scene/ground/scene/animation_root.gd @@ -16,7 +16,7 @@ var dialogue_c06 := preload("res://asset/dialogue/c06.dialogue") as DialogueReso @export_tool_button("reset 存档") var reset_archive = _reset_archive # event 也混合其中 @export var debug_global_data: Dictionary[String, Variant] = { - "enabled_items": ["prop_火柴", "prop_院长的信", "prop_银元"] as PackedStringArray, + "enabled_items": {}, "player_x": 30.0, } @export var debug_ground_data: Dictionary[String, Variant] = {} @@ -148,18 +148,6 @@ func _reset_archive() -> void: ResourceLoader.load("user://data/archives/save000.tres", "AssembledArchive") as AssembledArchive ) - archive.player_global_position_x = debug_global_data.get_or_add("player_x", 30.0) - # 重置全局变量 - var prop_arr = archive.prop_inventory.default_enabled_items - if get_node("../MainPlayer").character.begins_with("吕萍"): - prop_arr = archive.prop_inventory.xdie_enabled_items - elif get_node("../MainPlayer").character.begins_with("小小蝶"): - prop_arr = archive.prop_inventory.xxdie_enabled_items - elif get_node("../MainPlayer").character.begins_with("小小小蝶"): - prop_arr = archive.prop_inventory.xxxdie_enabled_items - for prop in debug_global_data["enabled_items"]: - if not prop_arr.has(prop): - prop_arr.append(prop) # 从 code 中找到 set_global_entry/get_global_value 方法中第一个 property var code = get_script().source_code # set_global_entry(property: StringName, value) @@ -214,11 +202,43 @@ func _reset_archive() -> void: events[key] = false print("Match event_getter: " + key) # 遍历 ".." 下所有节点,找到属于 Event2D 的节点 - _find_event2d(events, ground) - for e in events.keys(): + _find_event(events, ground) + for e in events: if debug_global_data.get(e) == null: debug_global_data[e] = 0 archive.event_stage[e] = debug_global_data[e] + # 重置 props 状态 + var props = debug_global_data["enabled_items"] as Dictionary + if props == null: + props = {} + debug_global_data["enabled_items"] = props + var prop_disabler_regx = RegEx.create_from_string(r'SceneManager.disable_prop_item\(.?"(.+)"') as RegEx + var prop_enabler_regx = RegEx.create_from_string(r'EventMSceneManageranager.enable_prop_item\(.?"(.+)"') as RegEx + for p_match in prop_disabler_regx.search_all(code): + var key = p_match.get_string(1) + if not props.has(key): + props[key] = true + print("Match global_data_setter: " + key) + for p_match in prop_enabler_regx.search_all(code): + var key = p_match.get_string(1) + if not props.has(key): + props[key] = false + print("Match global_data_getter: " + key) + _find_props(props, ground) + var prop_arr = archive.prop_inventory.default_enabled_items + if get_node("../MainPlayer").character.begins_with("吕萍"): + prop_arr = archive.prop_inventory.xdie_enabled_items + elif get_node("../MainPlayer").character.begins_with("小小蝶"): + prop_arr = archive.prop_inventory.xxdie_enabled_items + elif get_node("../MainPlayer").character.begins_with("小小小蝶"): + prop_arr = archive.prop_inventory.xxxdie_enabled_items + for prop in props: + if props[prop] and not prop_arr.has(prop): + prop_arr.append(prop) + if not props[prop] and prop_arr.has(prop): + prop_arr.erase(prop) + # 重置其他全局变量 + archive.player_global_position_x = debug_global_data.get_or_add("player_x", 30.0) print("reset archive data success") ResourceSaver.save(archive) notify_property_list_changed() @@ -243,7 +263,7 @@ func _setup_ground_data(g_data: Dictionary, node: Node): _setup_ground_data(g_data, child) -func _find_event2d(events: Dictionary, node: Node) -> void: +func _find_event(events: Dictionary, node: Node) -> void: if not node: return for child in node.get_children(): @@ -255,7 +275,35 @@ func _find_event2d(events: Dictionary, node: Node) -> void: if child.pre_event != &"": events[child.pre_event] = true print("Find pre_event: " + child.pre_event) - _find_event2d(events, child) + elif child is EventBinder: + print("Find EventBinder...") + if child.trigger_event != &"": + events[child.trigger_event] = true + print("Find trigger_event: " + child.trigger_event) + elif child.updater_event != &"": + events[child.updater_event] = true + print("Find updater_event: " + child.updater_event) + _find_event(events, child) + +func _find_props(props: Dictionary, node: Node) -> void: + if not node: + return + for child in node.get_children(): + if child is Interactable2D: + if child.prop_key != &"": + props[child.prop_key] = true + print("Find Interactable2D prop1: " + child.prop_key) + elif child.prop_key2 != &"": + props[child.prop_key2] = true + print("Find Interactable2D prop2: " + child.prop_key2) + elif child.prop_key3 != &"": + props[child.prop_key3] = true + print("Find Interactable2D prop3: " + child.prop_key3) + elif child is Pickable2D: + if child.prop_key != &"": + props[child.prop_key] = true + print("Find Pickable2D prop: " + child.prop_key) + _find_props(props, child) var func_line_id := -1 diff --git a/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd b/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd index 741c8653..d0bf0a08 100644 --- a/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd +++ b/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd @@ -81,7 +81,7 @@ func _on_ground_ready() -> void: # 玩家不能超过开始跑的位置 var player = SceneManager.get_player() as MainPlayer if player.position.x > 1800: - player.position.x = 1800 + player.update_x_with_camera_followed(1800) func _dean_flip_book() -> void: @@ -143,7 +143,7 @@ func _game_counting_down(_res = null): var player = SceneManager.get_player() as MainPlayer var left = player.global_position.x player.player_movement_rect.position.x = left - Util.timer(2.0, _kids_start_run) + Util.timer(1.0, _kids_start_run) cat.visible = true cat.play("【墙上黑猫】跑步") cat.get_node("猫咪嘶吼音效").play() @@ -184,11 +184,11 @@ var kid_run_tween func _kids_start_run(): standing_kid1.get_node("猫鼠游戏重置ambush").enabled = true + standing_kid2.get_node("猫鼠游戏重置ambush").enabled = true if kid_run_tween: kid_run_tween.kill() kid_run_tween = create_tween() # 奔跑 - kid_run_tween.tween_interval(1.0) kid_run_tween.tween_callback(standing_kid1.play.bind("【站立小孩-1】侧面跑步")) kid_run_tween.tween_interval(0.3) kid_run_tween.tween_callback(standing_kid2.play.bind("【站立小孩-2】侧面跑步")) @@ -206,27 +206,25 @@ func _kids_start_run(): # 中途推桌椅 func _on_push_obstacles(): obstacles_pushed = true + interactable_obstacles.enabled = false + obstacles.play("桌椅颤抖-翻倒") + $"桌椅撞倒音效".play() + _on_mid_ambush_success() + var player = SceneManager.get_player() as MainPlayer + # 禁止玩家越过桌椅 + player.player_movement_rect.position.x = 2850 + obstacles.play("桌椅颤抖-翻倒") + $"桌椅撞倒音效".play() + SceneManager.pop_debug_dialog_info("音效", "桌椅翻倒") +var current_round_failed = false # 小孩1首先跑到桌椅旁 func obstacles_ambush1_triggered(): - var player_x = SceneManager.get_player().global_position.x - # 桌椅右边缘的 x 坐标,桌椅生效条件:玩家在其右侧 + 交互过 - var obstacles_x = 2810 - if player_x < obstacles_x or not obstacles_pushed: - if GlobalConfig.DEBUG: - print("桌椅未发挥作用! player_x=", player_x, " obstacles_pushed=", obstacles_pushed) - obstacles.play("桌椅颤抖-正常") - SceneManager.pop_debug_dialog_info("美术", "桌椅颤抖-正常") - else: - # 禁止玩家越过桌椅 - var player = SceneManager.get_player() as MainPlayer - player.player_movement_rect.position.x = obstacles_x - obstacles.play("桌椅颤抖-翻倒") - $"桌椅撞倒音效".play() - _on_mid_ambush_success() - SceneManager.pop_debug_dialog_info("音效", "桌椅翻倒") + if obstacles_success: standing_kid1.play("【站立小孩-1】侧面呼吸") + else: + current_round_failed = true # 小孩2跑到桌椅旁 @@ -239,8 +237,10 @@ func obstacles_ambush2_triggered(): func obstacles_ambush3_triggered(): if obstacles_success: game_kid.play("【胖小孩背着残疾小孩】摔倒") - game_kid.sprite_frames.set_animation_loop("【胖小孩背着残疾小孩】摔倒", false) - game_kid.animation_finished.connect(_on_kid_fall_finished, CONNECT_ONE_SHOT) + # 只有第一个小孩没跑过去的时候,残疾小孩发动 + if not current_round_failed: + game_kid.sprite_frames.set_animation_loop("【胖小孩背着残疾小孩】摔倒", false) + game_kid.animation_finished.connect(_on_kid_fall_finished, CONNECT_ONE_SHOT) # 残疾小孩冲刺 @@ -267,6 +267,9 @@ func _on_mid_ambush_success(): func game_restart(): if kid_run_tween: kid_run_tween.kill() + current_round_failed = false + interactable_obstacles.enabled = true + obstacles_pushed = false standing_kid1.play("【站立小孩-1】侧面呼吸") standing_kid2.play("【站立小孩-2】侧面呼吸") game_kid.play("【胖小孩背着残疾小孩】侧面呼吸") @@ -281,7 +284,9 @@ func game_restart(): obstacles_success = false obstacles.get_node("遮盖").visible = false obstacles.play("桌椅正常") - SceneManager.get_player().global_position.x = 1800 + var player = SceneManager.get_player() + player.player_movement_rect.position.x = 1750 + player.global_position.x = 1800 var kids_start_run_initial_x = [1620, 1660, 1730] standing_kid1.global_position.x = kids_start_run_initial_x[0] standing_kid2.global_position.x = kids_start_run_initial_x[1] diff --git a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn index b07a3d33..0c805f1b 100644 --- a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn +++ b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn @@ -149,6 +149,57 @@ libraries = { &"": SubResource("AnimationLibrary_fq7pt") } script = ExtResource("2_fkfhi") +debug_global_data = Dictionary[String, Variant]({ +"enabled_items": {}, +"player_x": 2000.0 +}) +debug_ground_data = Dictionary[String, Variant]({ +"AnimationPlayer": { +"oneshot_animation_played": false +}, +"Interactable桌椅": { +"interacted_times": 0 +}, +"四小孩画鬼差的对话ambush": { +"played": false +}, +"对话1ambush": { +"played": false +}, +"对话2ambush": { +"played": false +}, +"对话3ambush": { +"played": false +}, +"桌椅ambush1": { +"played": false +}, +"桌椅ambush2": { +"played": false +}, +"桌椅ambush3": { +"played": false +}, +"猫鼠游戏失败ambush": { +"played": false +}, +"猫鼠游戏开始ambush": { +"played": false +}, +"猫鼠游戏胜利ambush": { +"played": false +}, +"猫鼠游戏重置ambush": { +"played": false +}, +"门口ambush": { +"played": false +}, +"门口对话ambush": { +"played": false +} +}) oneshot_animation = "" [node name="桌椅撞倒音效" type="AudioStreamPlayer2D" parent="Ground/AnimationPlayer" index="0"] @@ -208,7 +259,6 @@ visible = false position = Vector2(575, 9) enabled = false action = 3 -title_filter = "c01" note_key = "c01_s06_院长房间" [node name="Note小孩房间" parent="Ground/DeployLayer" index="3" instance=ExtResource("12_28t76")] @@ -216,7 +266,6 @@ visible = false position = Vector2(998, 2) enabled = false action = 3 -title_filter = "c01" note_key = "c01_s06_小朋友房间" [node name="门口对话ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("11_tudob")] @@ -242,6 +291,7 @@ speed = 90.0 position = Vector2(1241, -1) sprite_frames = ExtResource("2_l4axy") animation = &"秋千" +frame = 1 [node name="Sfx2D" type="AudioStreamPlayer2D" parent="Ground/DeployLayer/秋千"] process_mode = 1 @@ -270,6 +320,7 @@ metadata/_custom_type_script = "uid://wapo47a1oddf" position = Vector2(1358, 0) sprite_frames = ExtResource("2_l4axy") animation = &"跷跷板" +frame = 1 [node name="Sfx2D" type="AudioStreamPlayer2D" parent="Ground/DeployLayer/跷跷板"] process_mode = 1 @@ -318,6 +369,7 @@ action_configs = Array[Dictionary]([{ position = Vector2(43, -44.5) sprite_frames = ExtResource("7_dsj2r") animation = &"【画画男孩-1】呼吸" +frame = 1 action_configs = Array[Dictionary]([{ "animation_intro": "【画画男孩-1】呼吸", "animation_next": "【画画男孩-1】画画", @@ -331,9 +383,10 @@ action_configs = Array[Dictionary]([{ }]) [node name="游戏中途桌椅" parent="Ground/DeployLayer" index="11" instance=ExtResource("8_ouldg")] -position = Vector2(2838.5, 0.5) +position = Vector2(2791, 5) sprite_frames = ExtResource("7_dsj2r") animation = &"桌椅正常" +flip_h = true action_configs = Array[Dictionary]([{ "animation_intro": &"桌椅颤抖-正常", "animation_next": "桌椅正常", @@ -353,7 +406,7 @@ position = Vector2(-60, 117) texture = ExtResource("11_q3ypm") [node name="中途Trigger" type="Area2D" parent="Ground/DeployLayer/游戏中途桌椅"] -position = Vector2(-93.5, 30.5) +position = Vector2(34, 32) collision_layer = 64 collision_mask = 64 monitoring = false @@ -364,13 +417,15 @@ shape = SubResource("RectangleShape2D_1ojoa") debug_color = Color(0.519778, 0.447036, 0.929413, 0.42) [node name="Interactable桌椅" parent="Ground/DeployLayer" index="12" instance=ExtResource("12_idjp0")] -position = Vector2(2740.5, 50.5) +position = Vector2(2881, 49) +enable_snapper = false one_shot = false [node name="【站立小孩-3】" parent="Ground/DeployLayer" index="13" instance=ExtResource("8_ouldg")] position = Vector2(1558, -12) sprite_frames = ExtResource("7_dsj2r") animation = &"【站立小孩-3】呼吸" +frame = 1 action_configs = Array[Dictionary]([{ "animation_intro": &"【站立小孩-3】转身", "animation_next": "【站立小孩-3】走路", @@ -395,6 +450,7 @@ position = Vector2(1533, -5) sprite_frames = ExtResource("7_dsj2r") animation = &"【站立小孩-1】侧面呼吸" autoplay = "【站立小孩-1】侧面呼吸" +frame = 1 action_configs = Array[Dictionary]([{ "animation_intro": "【站立小孩-1】挠痒呼吸", "animation_next": "【站立小孩-1】走路", @@ -417,7 +473,7 @@ move_configs = Array[Dictionary]([{ "animation_next": "", "duration": 1e+07, "movement_x": 0.0, -"velocity": Vector2(115, 0) +"velocity": Vector2(101.5, 0) }]) [node name="桌椅ambush1" parent="Ground/DeployLayer/【站立小孩-1】" instance=ExtResource("11_tudob")] @@ -479,7 +535,7 @@ move_configs = Array[Dictionary]([{ "animation_next": "", "duration": 1e+07, "movement_x": 0.0, -"velocity": Vector2(110, 0) +"velocity": Vector2(102, 0) }]) [node name="FocusPoint" type="Node2D" parent="Ground/DeployLayer/【站立小孩-2】"] @@ -505,6 +561,18 @@ cooldown_time = 1.0 hook_dialogue_title = "c01_s06_四个小孩_对话2" hook_method = "talk2" +[node name="猫鼠游戏重置ambush" parent="Ground/DeployLayer/【站立小孩-2】" instance=ExtResource("11_tudob")] +position = Vector2(0, 53) +enabled = false +one_shot = false +hook_method = "game_restart" + +[node name="Sign" parent="Ground/DeployLayer/【站立小孩-2】/猫鼠游戏重置ambush" index="0"] +enabled = false + +[node name="CollisionShape2D" parent="Ground/DeployLayer/【站立小孩-2】/猫鼠游戏重置ambush/Area2D" index="0"] +shape = SubResource("RectangleShape2D_7cdhx") + [node name="【墙上黑猫】" parent="Ground/DeployLayer" index="16" instance=ExtResource("8_ouldg")] position = Vector2(1453, -14) scale = Vector2(0.8, 0.8) @@ -537,6 +605,7 @@ z_index = 1 position = Vector2(1733, 5) sprite_frames = ExtResource("7_dsj2r") animation = &"【胖小孩背着残疾小孩】画画" +frame = 7 action_configs = Array[Dictionary]([{ "animation_intro": "【胖小孩背着残疾小孩】呼吸", "animation_next": "【胖小孩背着残疾小孩】画画", @@ -563,7 +632,7 @@ move_configs = Array[Dictionary]([{ "animation_next": "", "duration": 1e+07, "movement_x": 0.0, -"velocity": Vector2(106, 0) +"velocity": Vector2(102, 0) }]) [node name="桌椅ambush3" parent="Ground/DeployLayer/【胖小孩背着残疾小孩】" instance=ExtResource("11_tudob")] @@ -652,6 +721,13 @@ offset = Vector2(601.5, -0.5) modulate = Color(0.931897, 0.931897, 0.931897, 1) position = Vector2(1575, 91) character = "小小蝶" +player_movement_rect = Rect2(37, -158, 3963, 316) + +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 5234 +limit_bottom = 158 [node name="院长凳子" type="Sprite2D" parent="Ground/ParallaxForeground/BGParallaxLayer" index="0"] position = Vector2(34, 3) @@ -669,17 +745,20 @@ position = Vector2(377, 18) scale = Vector2(0.9, 0.9) sprite_frames = ExtResource("2_l4axy") animation = &"中蓝衣小孩呼吸" +frame = 2 [node name="门口_右绿衣男孩" parent="Ground/ParallaxForeground/BGParallaxLayer" index="3" instance=ExtResource("8_ouldg")] position = Vector2(408, 3) sprite_frames = ExtResource("2_l4axy") animation = &"右绿衣男孩呼吸" +frame = 1 [node name="门口_红衣姑娘" parent="Ground/ParallaxForeground/BGParallaxLayer" index="4" instance=ExtResource("8_ouldg")] light_mask = 2 position = Vector2(333, 9.5) sprite_frames = ExtResource("2_l4axy") animation = &"红衣姑娘呼吸" +frame = 2 action_configs = Array[Dictionary]([{ "animation_intro": &"红衣姑娘抬头", "animation_next": "红衣姑娘呼吸", @@ -700,6 +779,7 @@ texture_scale = 0.5 position = Vector2(301, 8.5) sprite_frames = ExtResource("2_l4axy") animation = &"院长呼吸" +frame = 2 action_configs = Array[Dictionary]([{ "animation_intro": "院长翻书", "animation_next": "院长呼吸", @@ -716,6 +796,7 @@ action_configs = Array[Dictionary]([{ position = Vector2(273, 15) sprite_frames = ExtResource("2_l4axy") animation = &"左2黄衣男呼吸" +frame = 2 [node name="门口_左一绿衣男" parent="Ground/ParallaxForeground/BGParallaxLayer" index="7" instance=ExtResource("8_ouldg")] position = Vector2(242, 46.5) @@ -732,6 +813,7 @@ scale = Vector2(0.8, 0.8) sprite_frames = ExtResource("15_wtosl") animation = &"gif" autoplay = "gif" +frame = 1 centered = false offset = Vector2(0, -159) @@ -749,5 +831,6 @@ position = Vector2(0, -1) [editable path="Ground/DeployLayer/【站立小孩-1】/桌椅ambush1"] [editable path="Ground/DeployLayer/【站立小孩-1】/猫鼠游戏重置ambush"] [editable path="Ground/DeployLayer/【站立小孩-2】/桌椅ambush2"] +[editable path="Ground/DeployLayer/【站立小孩-2】/猫鼠游戏重置ambush"] [editable path="Ground/DeployLayer/【胖小孩背着残疾小孩】/桌椅ambush3"] [editable path="Ground/DeployLayer/【胖小孩背着残疾小孩】/【单残疾小孩】/猫鼠游戏失败ambush"] diff --git a/scene/ground/scene/c01/s07_书店外.tscn b/scene/ground/scene/c01/s07_书店外.tscn index 748d6459..f0b6f922 100644 --- a/scene/ground/scene/c01/s07_书店外.tscn +++ b/scene/ground/scene/c01/s07_书店外.tscn @@ -182,7 +182,7 @@ position = Vector2(1045, 6) sprite_frames = ExtResource("6_thm8f") animation = &"陆仁舞刀-黄昏带红缨" autoplay = "陆仁舞刀-黄昏带红缨" -frame = 62 +frame = 20 action_configs = Array[Dictionary]([{ "animation_intro": "陆仁收刀", &"animation_next": "陆仁收刀后呼吸", @@ -252,7 +252,7 @@ position = Vector2(2080, 6) sprite_frames = ExtResource("6_thm8f") animation = &"报童待机" autoplay = "报童待机" -frame = 2 +frame = 5 action_configs = Array[Dictionary]([{ "animation_intro": "报童给报纸", "animation_next": "报童待机", @@ -274,6 +274,13 @@ note_key = "c01_s07_书店展柜" [node name="MainPlayer" parent="Ground" index="5"] position = Vector2(41, 103) character = "小小蝶" +player_movement_rect = Rect2(37, -158, 2203, 316) + +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 2270 +limit_bottom = 158 [node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"] points = PackedVector2Array(37, 150, 2240, 150) diff --git a/scene/ground/scene/c01/s08_书店.gd b/scene/ground/scene/c01/s08_书店.gd index 009d7033..6f7068db 100644 --- a/scene/ground/scene/c01/s08_书店.gd +++ b/scene/ground/scene/c01/s08_书店.gd @@ -139,7 +139,7 @@ func _on_shelf_game_success() -> void: # 设置朝左,与书架的动画结尾一致 player.set_facing_direction(Vector2(-1, 0)) # 对齐位置 - player.global_position.x = 437 + player.update_x_with_camera_followed(437.0) # 相机抖动 SceneManager.get_camera_marker().shake_camera() # 播放小蝶从书架跌倒的动画 diff --git a/scene/ground/scene/c02/s01_公寓门口.gd b/scene/ground/scene/c02/s01_公寓门口.gd index 6505cc05..b8a833c9 100644 --- a/scene/ground/scene/c02/s01_公寓门口.gd +++ b/scene/ground/scene/c02/s01_公寓门口.gd @@ -16,7 +16,7 @@ func _ready() -> void: func _on_ground_ready() -> void: SceneManager.get_player().set_facing_direction(Vector2.RIGHT) - SceneManager.get_player().position.x = 78.0 + SceneManager.get_player().update_x_with_camera_followed(78.0) SceneManager.enable_important_item("prop_眼镜盒") SceneManager.enable_important_item("prop_船票") await SceneManager.pop_os_with_str("c02_s01_下黄包车") diff --git a/scene/ground/scene/c02/s01_公寓门口.tscn b/scene/ground/scene/c02/s01_公寓门口.tscn index 6dc19b88..12f5cb28 100644 --- a/scene/ground/scene/c02/s01_公寓门口.tscn +++ b/scene/ground/scene/c02/s01_公寓门口.tscn @@ -96,6 +96,13 @@ height = 40.0 [node name="MainPlayer" parent="Ground" index="5"] position = Vector2(78, 98) +player_movement_rect = Rect2(37, -158, 683, 316) + +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 755 +limit_bottom = 158 [node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"] points = PackedVector2Array(37, 150, 720, 150) diff --git a/scene/ground/scene/c02/s03_院子.tscn b/scene/ground/scene/c02/s03_院子.tscn index 26093868..b6f13ecf 100644 --- a/scene/ground/scene/c02/s03_院子.tscn +++ b/scene/ground/scene/c02/s03_院子.tscn @@ -428,7 +428,6 @@ position = Vector2(953, 42) sprite_frames = ExtResource("11_o1qbs") animation = &"c00_头套小婵_run" autoplay = "c00_头套小婵_idle" -frame = 5 move_configs = Array[Dictionary]([{ "animation": "c00_头套小婵_run", "animation_next": "", @@ -782,7 +781,7 @@ position = Vector2(29, -3) sprite_frames = ExtResource("34_1tart") animation = &"小婵_被霸凌" autoplay = "小婵_被霸凌" -frame = 2 +frame = 1 [node name="f1" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")] z_index = 10 @@ -790,7 +789,7 @@ position = Vector2(-11, 1) sprite_frames = ExtResource("34_1tart") animation = &"霸凌1" autoplay = "霸凌1" -frame = 4 +frame = 3 [node name="Sfx2D霸凌童谣" type="AudioStreamPlayer2D" parent="Ground/DeployLayer/霸凌/f1"] process_mode = 1 @@ -808,7 +807,7 @@ position = Vector2(23, 11) sprite_frames = ExtResource("34_1tart") animation = &"霸凌2" autoplay = "霸凌2" -frame = 1 +frame = 3 [node name="f3" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")] z_index = 10 @@ -816,7 +815,7 @@ position = Vector2(57, 7) sprite_frames = ExtResource("34_1tart") animation = &"霸凌3" autoplay = "霸凌3" -frame = 9 +frame = 3 [node name="Ambush点火游戏阻挡右移" parent="Ground/DeployLayer/霸凌" instance=ExtResource("25_iyaiw")] position = Vector2(-116, -13) @@ -1005,7 +1004,6 @@ position = Vector2(2229, 41) sprite_frames = ExtResource("34_1tart") animation = &"霸凌3-发抖" autoplay = "霸凌3-发抖" -frame = 1 [node name="Pro小孩喊着火啦3" parent="Ground/DeployLayer/火灾" instance=ExtResource("33_ycojw")] z_index = 9 @@ -1064,7 +1062,6 @@ z_index = 5 position = Vector2(17, -11) sprite_frames = ExtResource("39_rnk1v") animation = &"吕萍牵手动作" -frame = 5 [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/牵手跑"] shape = SubResource("RectangleShape2D_vddfx") diff --git a/scene/ground/scene/c02/s04_保卫科.tscn b/scene/ground/scene/c02/s04_保卫科.tscn index ebbd82b1..9a4903b5 100644 --- a/scene/ground/scene/c02/s04_保卫科.tscn +++ b/scene/ground/scene/c02/s04_保卫科.tscn @@ -155,8 +155,15 @@ animation = &"c00_头套小婵_write" [node name="MainPlayer" parent="Ground" index="5"] position = Vector2(447, 98) +player_movement_rect = Rect2(66, -158, 429, 316) facing_direction = Vector2(-1, 0) +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 564 +limit_bottom = 158 + [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] position = Vector2(45, -76) scale = Vector2(1.05, 1.05) diff --git a/scene/ground/scene/c02/s06_二楼.gd b/scene/ground/scene/c02/s06_二楼.gd index 33d3b91d..97231759 100644 --- a/scene/ground/scene/c02/s06_二楼.gd +++ b/scene/ground/scene/c02/s06_二楼.gd @@ -143,7 +143,7 @@ func _on_ball_game_exit(success = null): func _c02_final_show(): var player = SceneManager.get_player() player.set_facing_direction(Vector2(-1, 0)) - player.global_position.x = 650 + player.update_x_with_camera_followed(650.0) player.visible = false SceneManager.lock_player() # 整体流程:c02_final_show_join - 特写 - c02_final_show_end diff --git a/scene/ground/scene/c02/s06_二楼.tscn b/scene/ground/scene/c02/s06_二楼.tscn index d8bec87f..83389471 100644 --- a/scene/ground/scene/c02/s06_二楼.tscn +++ b/scene/ground/scene/c02/s06_二楼.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=62 format=3 uid="uid://cootarwb44vvh"] +[gd_scene load_steps=63 format=3 uid="uid://cootarwb44vvh"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qkymk"] [ext_resource type="Script" uid="uid://cbt0ubygchxvv" path="res://scene/ground/scene/c02/s06_二楼.gd" id="2_4dg6u"] @@ -33,6 +33,7 @@ [ext_resource type="AudioStream" uid="uid://fc7ocwfmtjyb" path="res://asset/audio/sfx/交互/第一章/sfx_撞墙1.wav" id="17_4lf48"] [ext_resource type="AudioStream" uid="uid://cw6ho7gklq2sa" path="res://asset/audio/sfx/交互/第一章/sfx_撞墙2.wav" id="18_m28ab"] [ext_resource type="Texture2D" uid="uid://0x7cl2cmcs6l" path="res://asset/art/scene/c02/s03_公寓一楼院子/光晕/光晕2.png" id="18_rjlld"] +[ext_resource type="Texture2D" uid="uid://d33jmss6vlhk7" path="res://asset/art/scene/c02/s03_公寓一楼院子/地面物品反光/地反光2.png" id="21_2rktm"] [ext_resource type="PackedScene" uid="uid://bait5vh6jhmss" path="res://scene/ground/script/c02/谢幕演出.tscn" id="25_m28ab"] [ext_resource type="AudioStream" uid="uid://bxp3f263aaqkp" path="res://asset/audio/sfx/脚步/02_室外_1.wav" id="29_tqnu8"] [ext_resource type="AudioStream" uid="uid://d3h0xe0qtai18" path="res://asset/audio/sfx/脚步/02_室外_2.wav" id="30_r7b2r"] @@ -893,25 +894,27 @@ libraries = { script = ExtResource("2_4dg6u") debug_global_data = Dictionary[String, Variant]({ "c02_2f_xchan_run_away": 0, -"c02_ball_game_stage": 3, -"c02_burning": false, -"c02_burning_end_stage": 1, +"c02_ball_game_stage": 1, +"c02_burning_end_stage": 2, "c02_madman_hitwall": false, "c02_mouse_follow_player": false, "c02_pliers_to_ball": false, "c02_s02_mouse_push_shoe": false, -"c02_the_blind_room_unlocked": true, -"enabled_items": ["prop_火柴", "prop_院长的信", "prop_弹珠"], +"c02_the_blind_room_unlocked": false, +"enabled_items": { +"prop_小鞋子1": true, +"prop_火柴": true +}, "handnote_c02_map_2": 0, "handnote_c02_shoe_giveToMouce": 0, -"player_x": 30.0 +"player_x": 830.0 }) debug_ground_data = Dictionary[String, Variant]({ "Ambush三男孩": { "played": false }, "Ambush小蝉偷看": { -"played": true +"played": false }, "Ambush解锁二楼地图": { "played": false @@ -934,14 +937,8 @@ debug_ground_data = Dictionary[String, Variant]({ "Interactable老鼠洞": { "interacted_times": 0 }, -"Pickable小猫纸条": { -"picked": false -}, "煤油灯": { "interacted_times": 0 -}, -"煤油灯2": { -"interacted_times": 0 } }) oneshot_animation = "" @@ -1118,6 +1115,13 @@ energy = 2.0 blend_mode = 2 texture = ExtResource("18_rjlld") +[node name="地面光" type="PointLight2D" parent="Ground/DeployLayer/煤油灯2"] +position = Vector2(12, 5) +energy = 1.5 +blend_mode = 2 +range_item_cull_mask = 4 +texture = ExtResource("21_2rktm") + [node name="Interactable老鼠洞" parent="Ground/DeployLayer" index="10" instance=ExtResource("7_0d746")] position = Vector2(618, 50) enabled = false @@ -1353,7 +1357,6 @@ position = Vector2(269, 57) sprite_frames = ExtResource("40_7i4w0") animation = &"c00_头套小婵_idle" autoplay = "c00_头套小婵_idle" -frame = 1 flip_h = true move_configs = Array[Dictionary]([{ "animation": "c00_头套小婵_run", @@ -1367,8 +1370,15 @@ debug_mov_animation = "c00_头套小婵_run" [node name="MainPlayer" parent="Ground" index="5"] position = Vector2(63, 95) catty_light_energy = 0.5 +player_movement_rect = Rect2(26, -158, 874, 316) facing_direction = Vector2(1, 0) +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 927 +limit_bottom = 158 + [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] position = Vector2(0, -5) scale = Vector2(1.1, 1.1) @@ -1378,6 +1388,7 @@ texture = ExtResource("5_26mqt") points = PackedVector2Array(26, 150, 900, 150) [node name="DirectionalLight2D" parent="Ground" index="8"] +visible = false energy = 0.9 blend_mode = 1 diff --git a/scene/ground/scene/c02/s07_二楼内侧楼道.tscn b/scene/ground/scene/c02/s07_二楼内侧楼道.tscn index 4d8a7101..cf00e8ce 100644 --- a/scene/ground/scene/c02/s07_二楼内侧楼道.tscn +++ b/scene/ground/scene/c02/s07_二楼内侧楼道.tscn @@ -128,6 +128,13 @@ prop_key = "prop_粘鼠板" [node name="MainPlayer" parent="Ground" index="5"] position = Vector2(41, 98) +player_movement_rect = Rect2(37, -158, 573, 316) + +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 645 +limit_bottom = 158 [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] position = Vector2(11, -1) diff --git a/scene/ground/scene/c02/s08_瞎子卧室.gd b/scene/ground/scene/c02/s08_瞎子卧室.gd index 6f00696f..35a346fc 100644 --- a/scene/ground/scene/c02/s08_瞎子卧室.gd +++ b/scene/ground/scene/c02/s08_瞎子卧室.gd @@ -141,7 +141,7 @@ func enter_room() -> void: sprite.frame = 0 sprite.play() await tween.finished - player.position.x = player_x + player.update_x_with_camera_followed(player_x) setup_rect_after_entered() sprite.visible = false player.hide_sprite = false diff --git a/scene/ground/scene/c02/s08_瞎子卧室.tscn b/scene/ground/scene/c02/s08_瞎子卧室.tscn index fac84ca8..b78e6fa5 100644 --- a/scene/ground/scene/c02/s08_瞎子卧室.tscn +++ b/scene/ground/scene/c02/s08_瞎子卧室.tscn @@ -350,6 +350,7 @@ occluder = SubResource("OccluderPolygon2D_qem0g") position = Vector2(513, 88) lock_move_right = true character = "吕萍爬行" +player_movement_rect = Rect2(580, -158, 110, 316) facing_direction = Vector2(-1, 0) [node name="PointLight2D2" type="PointLight2D" parent="Ground/MainPlayer" index="6"] @@ -362,6 +363,12 @@ texture = SubResource("GradientTexture2D_bp5fr") [node name="AudioListener2D" type="AudioListener2D" parent="Ground/MainPlayer" index="7"] current = true +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 725 +limit_bottom = 158 + [node name="Sprite2D" type="Sprite2D" parent="Ground/ParallaxForeground/BGParallaxLayer" index="0"] position = Vector2(291, 94) texture = ExtResource("4_gx8oy") diff --git a/scene/ground/scene/c02/s10_空房间.tscn b/scene/ground/scene/c02/s10_空房间.tscn index 998632df..a098c00f 100644 --- a/scene/ground/scene/c02/s10_空房间.tscn +++ b/scene/ground/scene/c02/s10_空房间.tscn @@ -303,8 +303,15 @@ texture = SubResource("GradientTexture2D_3ftnp") [node name="MainPlayer" parent="Ground" index="5"] position = Vector2(315, 98) +player_movement_rect = Rect2(50, -158, 460, 316) facing_direction = Vector2(1, 0) +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 564 +limit_bottom = 158 + [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] visible = false position = Vector2(193, 0) diff --git a/scene/ground/scene/c02/s12_盒子猫.gd b/scene/ground/scene/c02/s12_盒子猫.gd index 0e934084..f67a4422 100644 --- a/scene/ground/scene/c02/s12_盒子猫.gd +++ b/scene/ground/scene/c02/s12_盒子猫.gd @@ -22,7 +22,7 @@ func _on_ground_ready() -> void: print("[盒子猫] intro start") SceneManager.lock_player() player.hide_sprite = true - player.position.x = 232.0 + player.update_x_with_camera_followed(232.0) var layer = $"../盒子猫CanvasLayer" layer.disable_crawl = true var duration = layer.show_cat_duration diff --git a/scene/ground/scene/c03/s01_三楼.tscn b/scene/ground/scene/c03/s01_三楼.tscn index bb4c1e34..00254624 100644 --- a/scene/ground/scene/c03/s01_三楼.tscn +++ b/scene/ground/scene/c03/s01_三楼.tscn @@ -1,10 +1,25 @@ -[gd_scene load_steps=10 format=3 uid="uid://dlrbhfvnd3cs0"] +[gd_scene load_steps=32 format=3 uid="uid://dlrbhfvnd3cs0"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_eb2op"] [ext_resource type="Script" uid="uid://c0rh2n36ait6i" path="res://scene/ground/scene/c03/s01_三楼.gd" id="2_ow08b"] [ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_lb1oo"] [ext_resource type="Texture2D" uid="uid://cpjd3dqri51fq" path="res://asset/art/scene/c03/s01_三楼/bg_三楼走廊.png" id="4_ow08b"] +[ext_resource type="Texture2D" uid="uid://b7t2sfe5ugtsc" path="res://asset/art/scene/c03/引导纸人/指引纸人3.png" id="5_fnwup"] [ext_resource type="Texture2D" uid="uid://djoft6600kly6" path="res://asset/art/scene/c03/s01_三楼/fg_前景.png" id="5_ow08b"] +[ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="5_tutxu"] +[ext_resource type="PackedScene" uid="uid://dqkxiqbq83cmq" path="res://scene/entity/closeup.tscn" id="6_obrgj"] +[ext_resource type="Script" uid="uid://0wjaho6qkg6s" path="res://manager/event_manager/event_binder.gd" id="6_yaa68"] +[ext_resource type="PackedScene" uid="uid://wvb1wy8l28et" path="res://scene/ground/script/c03/s01_closeup_demo公告.tscn" id="7_d27sg"] +[ext_resource type="Script" uid="uid://bkkiyk5jkdw4d" path="res://manager/event_manager/event2d.gd" id="7_obrgj"] +[ext_resource type="SpriteFrames" uid="uid://cljrkkmy2pwdp" path="res://asset/art/gif/c03_三楼/c03_三楼_frames.tres" id="10_krvxg"] +[ext_resource type="Texture2D" uid="uid://bp84w8keuelyj" path="res://asset/art/scene/c02/s10_空房间/e_蜡烛-sheet.png" id="11_4y4hg"] +[ext_resource type="Texture2D" uid="uid://brsrkwf0k0bpn" path="res://asset/art/scene/demo额外/demo感谢告示(场景).png" id="11_amci2"] +[ext_resource type="Texture2D" uid="uid://cylsq5cvhlp18" path="res://asset/art/tool/point_light.png" id="12_5ov12"] +[ext_resource type="Texture2D" uid="uid://1pr32tkx4ttl" path="res://asset/art/scene/c02/s03_公寓一楼院子/e_煤油灯座.png" id="13_1031a"] +[ext_resource type="SpriteFrames" uid="uid://3nas025c2c5u" path="res://asset/art/gif/c02_杂项/c02_杂项_frames.tres" id="14_v0mby"] +[ext_resource type="Texture2D" uid="uid://0x7cl2cmcs6l" path="res://asset/art/scene/c02/s03_公寓一楼院子/光晕/光晕2.png" id="15_fnwup"] +[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="18_0xq6i"] +[ext_resource type="Texture2D" uid="uid://dagy852q0fduh" path="res://asset/art/scene/c03/s01_三楼/e_治病木牌.png" id="19_hmme5"] [sub_resource type="Animation" id="Animation_k01ve"] length = 0.001 @@ -108,7 +123,55 @@ _data = { &"c02_final_show_join": SubResource("Animation_ciatp") } +[sub_resource type="Gradient" id="Gradient_krvxg"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0, 0.693168, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_4rrrd"] +gradient = SubResource("Gradient_krvxg") +height = 100 +fill = 2 +fill_from = Vector2(0.5, 0.5) + +[sub_resource type="AtlasTexture" id="AtlasTexture_chbaa"] +atlas = ExtResource("11_4y4hg") +region = Rect2(0, 0, 6, 14) + +[sub_resource type="AtlasTexture" id="AtlasTexture_th1ek"] +atlas = ExtResource("11_4y4hg") +region = Rect2(6, 0, 6, 14) + +[sub_resource type="AtlasTexture" id="AtlasTexture_to1d1"] +atlas = ExtResource("11_4y4hg") +region = Rect2(12, 0, 6, 14) + +[sub_resource type="AtlasTexture" id="AtlasTexture_nx6jy"] +atlas = ExtResource("11_4y4hg") +region = Rect2(18, 0, 6, 14) + +[sub_resource type="SpriteFrames" id="SpriteFrames_w4rk2"] +animations = [{ +"frames": [{ +"duration": 3.0, +"texture": SubResource("AtlasTexture_chbaa") +}, { +"duration": 3.0, +"texture": SubResource("AtlasTexture_th1ek") +}, { +"duration": 3.0, +"texture": SubResource("AtlasTexture_to1d1") +}, { +"duration": 3.0, +"texture": SubResource("AtlasTexture_nx6jy") +}], +"loop": true, +"name": &"default", +"speed": 10.0 +}] + [node name="S01" type="Node2D"] +metadata/_edit_horizontal_guides_ = [98.0] [node name="Ground" parent="." instance=ExtResource("1_eb2op")] scene_name = "c03_s01" @@ -120,7 +183,22 @@ libraries = { } script = ExtResource("2_ow08b") debug_global_data = Dictionary[String, Variant]({ -"enabled_items": ["prop_火柴", "prop_院长的信", "prop_银元"] +"c03_s01_meat_put": 0, +"enabled_items": Dictionary[String, bool]({ +"prop_奇怪的肉": true +}), +"player_x": 500.0 +}) +debug_ground_data = Dictionary[String, Variant]({ +"AnimationPlayer": { +"oneshot_animation_played": false +}, +"CloseupDemo公告": { +"interacted_times": 0 +}, +"Interactable放肉处": { +"interacted_times": 0 +} }) oneshot_animation = "" @@ -133,29 +211,178 @@ metadata/_custom_type_script = "uid://cpejxlfni6n52" light_mask = 5 position = Vector2(0, -2) texture = ExtResource("4_ow08b") +offset = Vector2(0, -115.5) [node name="portal_left" parent="Ground/DeployLayer" index="0"] position = Vector2(34, 8) -target_scene = "c02_s07" -target_portal = "1" [node name="portal_right" parent="Ground/DeployLayer" index="1"] position = Vector2(697, 18) target_scene = "c02_s06" target_portal = "right" +[node name="互动公告" type="Sprite2D" parent="Ground/DeployLayer" index="2"] +position = Vector2(377, 30) +scale = Vector2(0.8, 0.8) +texture = ExtResource("5_fnwup") +flip_h = true + +[node name="Note治病木牌" parent="Ground/DeployLayer" index="3" instance=ExtResource("18_0xq6i")] +position = Vector2(456, 47) +texture = ExtResource("19_hmme5") +title_filter = "c03" +note_key = "c03_s01_门口看病牌子" + +[node name="Interactable放肉处" parent="Ground/DeployLayer" index="4" instance=ExtResource("5_tutxu")] +position = Vector2(567, 39) +prop_key = "prop_奇怪的肉" + +[node name="EventBinder" type="Node" parent="Ground/DeployLayer/Interactable放肉处"] +script = ExtResource("6_yaa68") +trigger_event = &"c03_s01_meat_put" +trigger_mode = "interacted" +metadata/_custom_type_script = "uid://0wjaho6qkg6s" + +[node name="Event2D放肉后" type="Node2D" parent="Ground/DeployLayer" index="5"] +script = ExtResource("7_obrgj") +event = &"c03_s01_meat_put" +hide_if_on_stage = Array[int]([0, 2]) +metadata/_custom_type_script = "uid://bkkiyk5jkdw4d" + +[node name="窗口闪动" type="AnimatedSprite2D" parent="Ground/DeployLayer/Event2D放肉后"] +position = Vector2(434, -15) +sprite_frames = ExtResource("10_krvxg") +animation = &"三楼窗户动画" +autoplay = "三楼窗户动画" +frame = 5 +frame_progress = 0.482491 + +[node name="PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/Event2D放肉后/窗口闪动"] +scale = Vector2(1.12987, 0.87752) +texture = SubResource("GradientTexture2D_4rrrd") + +[node name="CloseupDemo公告" parent="Ground/DeployLayer/Event2D放肉后" instance=ExtResource("6_obrgj")] +position = Vector2(573, -6) +texture = ExtResource("11_amci2") +packed_scene = ExtResource("7_d27sg") + +[node name="小蜡烛系列" type="Node2D" parent="Ground/DeployLayer" index="6"] +position = Vector2(0, 3) + +[node name="小蜡烛" type="AnimatedSprite2D" parent="Ground/DeployLayer/小蜡烛系列"] +self_modulate = Color(0.611765, 0.611765, 0.611765, 1) +position = Vector2(680, 48) +sprite_frames = SubResource("SpriteFrames_w4rk2") +autoplay = "default" + +[node name="小蜡烛PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/小蜡烛系列/小蜡烛"] +position = Vector2(0, -12.8172) +color = Color(0.999971, 0.912551, 0.842208, 1) +energy = 1.2 +blend_mode = 2 +texture = ExtResource("12_5ov12") +texture_scale = 0.3 + +[node name="小蜡烛2" type="AnimatedSprite2D" parent="Ground/DeployLayer/小蜡烛系列"] +self_modulate = Color(0.611765, 0.611765, 0.611765, 1) +position = Vector2(585, 51) +sprite_frames = SubResource("SpriteFrames_w4rk2") +autoplay = "default" + +[node name="小蜡烛PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/小蜡烛系列/小蜡烛2"] +position = Vector2(0, -12.8172) +color = Color(0.999971, 0.912551, 0.842208, 1) +energy = 1.2 +blend_mode = 2 +texture = ExtResource("12_5ov12") +texture_scale = 0.3 + +[node name="小蜡烛3" type="AnimatedSprite2D" parent="Ground/DeployLayer/小蜡烛系列"] +self_modulate = Color(0.611765, 0.611765, 0.611765, 1) +position = Vector2(283, -3) +sprite_frames = SubResource("SpriteFrames_w4rk2") +autoplay = "default" + +[node name="小蜡烛PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/小蜡烛系列/小蜡烛3"] +position = Vector2(0, -12.8172) +color = Color(0.999971, 0.912551, 0.842208, 1) +energy = 1.2 +blend_mode = 2 +texture = ExtResource("12_5ov12") +texture_scale = 0.3 + +[node name="小蜡烛4" type="AnimatedSprite2D" parent="Ground/DeployLayer/小蜡烛系列"] +self_modulate = Color(0.611765, 0.611765, 0.611765, 1) +position = Vector2(106, 4) +sprite_frames = SubResource("SpriteFrames_w4rk2") +autoplay = "default" + +[node name="小蜡烛PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/小蜡烛系列/小蜡烛4"] +position = Vector2(0, -12.8172) +color = Color(0.999971, 0.912551, 0.842208, 1) +energy = 1.2 +blend_mode = 2 +texture = ExtResource("12_5ov12") +texture_scale = 0.3 + +[node name="小蜡烛5" type="AnimatedSprite2D" parent="Ground/DeployLayer/小蜡烛系列"] +self_modulate = Color(0.611765, 0.611765, 0.611765, 1) +position = Vector2(223, -49) +sprite_frames = SubResource("SpriteFrames_w4rk2") +autoplay = "default" + +[node name="小蜡烛PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/小蜡烛系列/小蜡烛5"] +position = Vector2(0, -12.8172) +color = Color(0.999971, 0.912551, 0.842208, 1) +energy = 1.2 +blend_mode = 2 +texture = ExtResource("12_5ov12") +texture_scale = 0.3 + +[node name="煤油灯2" type="Sprite2D" parent="Ground/DeployLayer" index="7"] +position = Vector2(469, 2) +texture = ExtResource("13_1031a") + +[node name="灯光" type="AnimatedSprite2D" parent="Ground/DeployLayer/煤油灯2"] +position = Vector2(4.5, -28) +scale = Vector2(0.3, 0.3) +sprite_frames = ExtResource("14_v0mby") +animation = &"火苗" +autoplay = "火苗" + +[node name="PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/煤油灯2"] +position = Vector2(11, -17) +color = Color(1, 0.882353, 0.705882, 1) +energy = 2.0 +blend_mode = 2 +texture = ExtResource("15_fnwup") + +[node name="纸人" type="Sprite2D" parent="Ground/DeployLayer" index="8"] +position = Vector2(377, 30) +scale = Vector2(0.8, 0.8) +texture = ExtResource("5_fnwup") +flip_h = true + [node name="MainPlayer" parent="Ground" index="5"] -position = Vector2(63, 95) +position = Vector2(34, 98) catty_light_energy = 0.5 +player_movement_rect = Rect2(30, -158, 693, 316) facing_direction = Vector2(1, 0) +[node name="CameraFocusMarker" parent="Ground" index="6"] +limit_left = 0 +limit_top = -158 +limit_right = 749 +limit_bottom = 158 + [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] +visible = false position = Vector2(0, -5) scale = Vector2(1.1, 1.1) texture = ExtResource("5_ow08b") [node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"] -points = PackedVector2Array(26, 150, 900, 150) +points = PackedVector2Array(30, 151, 723, 150) [node name="DirectionalLight2D" parent="Ground" index="8"] visible = false diff --git a/scene/ground/script/c02/s08_画特写.tscn b/scene/ground/script/c02/s08_画特写.tscn index 16aa0d5e..50e9c991 100644 --- a/scene/ground/script/c02/s08_画特写.tscn +++ b/scene/ground/script/c02/s08_画特写.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=6 format=3 uid="uid://dd8dfoik0ig3y"] -[ext_resource type="Script" uid="uid://dnrql1t0j6v8i" path="res://scene/ground/script/c02/通用特写脚本.gd" id="1_jgyts"] +[ext_resource type="Script" uid="uid://dnrql1t0j6v8i" path="res://scene/entity/closeup_template.gd" id="1_jgyts"] [ext_resource type="Texture2D" uid="uid://d1seskftkw08q" path="res://asset/art/scene/c02/s08_瞎子卧室/ux_盒子猫初次特写.png" id="2_jo6o1"] [ext_resource type="Texture2D" uid="uid://cbql1i4hblmt1" path="res://asset/art/ui/遮罩/inspect特写通用遮罩.png" id="3_myoho"] [ext_resource type="PackedScene" uid="uid://dmysq4sxx8iqh" path="res://scene/entity/ux/content_inspector.tscn" id="4_4p6cc"] diff --git a/scene/ground/script/c02/s08_画特写2.tscn b/scene/ground/script/c02/s08_画特写2.tscn index d8138d52..b9c69817 100644 --- a/scene/ground/script/c02/s08_画特写2.tscn +++ b/scene/ground/script/c02/s08_画特写2.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=8 format=3 uid="uid://cxv7vdgwb8lqb"] -[ext_resource type="Script" uid="uid://dnrql1t0j6v8i" path="res://scene/ground/script/c02/通用特写脚本.gd" id="1_2sinf"] +[ext_resource type="Script" uid="uid://dnrql1t0j6v8i" path="res://scene/entity/closeup_template.gd" id="1_2sinf"] [ext_resource type="Texture2D" uid="uid://k6164drvkbg8" path="res://asset/art/scene/c02/s08_瞎子卧室/ux_盒子猫结束特写.png" id="2_qrck0"] [ext_resource type="Texture2D" uid="uid://cbql1i4hblmt1" path="res://asset/art/ui/遮罩/inspect特写通用遮罩.png" id="3_7dv3t"] [ext_resource type="Texture2D" uid="uid://tcjm158n8hnw" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/小脚脚印.png" id="4_tja8r"] diff --git a/scene/ground/script/c02/追猫猪头怪.gd b/scene/ground/script/c02/追猫猪头怪.gd index 4753c608..80402baa 100644 --- a/scene/ground/script/c02/追猫猪头怪.gd +++ b/scene/ground/script/c02/追猫猪头怪.gd @@ -7,7 +7,7 @@ extends Node2D # 追击速度 @export var speed := 50 # 转身范围,超过这个范围/在这个范围内不 hidden 都会转身 -@export var trun_back_detact_x := 150 +@export var trun_back_detect_x := 150 # 抓取范围,优先 catch_front 播放 猪头怪抓盒子猫 # 其次 catch_nearby 播放 猪头怪抓盒子猫后段 @export var catch_front_x_range := Vector2(55 - 3, 55 + 3) @@ -22,17 +22,17 @@ var allow_restart_game := true @onready var sprite2d = $AnimatedSprite2D as AnimatedSprite2D # 检测到猫钻进盒子的过程 -var cat_hiding_detacted = false +var cat_hiding_detected = false var footstep_timer := Timer.new() var player var camera var catty_canvas_layer # 运动&检测, 初始为 false -var move_and_detact = false: +var move_and_detect = false: set(val): - move_and_detact = val - toggle_footstep_sfx(move_and_detact) + move_and_detect = val + toggle_footstep_sfx(move_and_detect) if val and is_node_ready(): sprite2d.play("猪头怪走路") # 启用的瞬间先执行检测 @@ -94,7 +94,7 @@ func _on_ground_ready(): if GlobalConfig.DEBUG: print("猪头怪 Transfer to: " + portal) else: - move_and_detact = true + move_and_detect = true var footstep_count := 0 @@ -141,17 +141,17 @@ func _do_transfer(): var tween = create_tween() tween.tween_property(self, "modulate:a", 1.0, 2.0) await tween.finished - move_and_detact = true + move_and_detect = true # 转身追击 func turn_back(): - move_and_detact = false + move_and_detect = false # 呼吸一帧,然后转身 sprite2d.play("猪头怪呼吸") await sprite2d.animation_looped _toggle_flip_h() - move_and_detact = true + move_and_detect = true func _toggle_flip_h(): @@ -161,7 +161,7 @@ func _toggle_flip_h(): # 抓小猫 func do_catch(front: bool): - move_and_detact = false + move_and_detect = false SceneManager.freeze_player(0) # 抓小猫时 lock palyer SceneManager.lock_player() @@ -187,7 +187,7 @@ func do_catch(front: bool): func _physics_process(delta: float) -> void: - if not move_and_detact: + if not move_and_detect: return var player_pos = player.global_position @@ -202,13 +202,13 @@ func _physics_process(delta: float) -> void: # 检查隐藏小猫,在观测范围内进入盒子仍旧会被抓 if signed_x_diff < 0 or signed_x_diff > watching_x: - # 如果离开一定范围,重置 cat_hiding_detacted - cat_hiding_detacted = false + # 如果离开一定范围,重置 cat_hiding_detected + cat_hiding_detected = false else: - cat_hiding_detacted = cat_hiding_detacted or not is_cat_hideen + cat_hiding_detected = cat_hiding_detected or not is_cat_hideen # 检查是否抓取 - if cat_hiding_detacted or not is_cat_hideen: + if cat_hiding_detected or not is_cat_hideen: if signed_x_diff > catch_front_x_range.x and signed_x_diff < catch_front_x_range.y: # 优先 catch_front 播放 猪头怪抓盒子猫 do_catch(true) @@ -219,7 +219,7 @@ func _physics_process(delta: float) -> void: return # 检查是否需要转身,超过这个范围/在这个范围内不 hidden 都会转身 - if signed_x_diff < 0 and trun_back_detact_x < -signed_x_diff: + if signed_x_diff < 0 and trun_back_detect_x < -signed_x_diff: turn_back() return diff --git a/scene/ground/script/c03/s01_closeup_demo公告.gd b/scene/ground/script/c03/s01_closeup_demo公告.gd new file mode 100644 index 00000000..e7cf2c82 --- /dev/null +++ b/scene/ground/script/c03/s01_closeup_demo公告.gd @@ -0,0 +1,10 @@ +extends CanvasLayer + +@onready var bg = $BG as TextureRect + + +func _ready() -> void: + layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME + # 非中文使用 6 号字,中文使用 8 号字 + if not TranslationServer.get_locale().begins_with("zh"): + %"公告正文".set("theme_override_font_sizes/font_size", 6) diff --git a/scene/ground/script/c03/s01_closeup_demo公告.gd.uid b/scene/ground/script/c03/s01_closeup_demo公告.gd.uid new file mode 100644 index 00000000..5220ae22 --- /dev/null +++ b/scene/ground/script/c03/s01_closeup_demo公告.gd.uid @@ -0,0 +1 @@ +uid://dtc8338f82g3n diff --git a/scene/ground/script/c03/s01_closeup_demo公告.tscn b/scene/ground/script/c03/s01_closeup_demo公告.tscn new file mode 100644 index 00000000..8d84caac --- /dev/null +++ b/scene/ground/script/c03/s01_closeup_demo公告.tscn @@ -0,0 +1,81 @@ +[gd_scene load_steps=6 format=3 uid="uid://wvb1wy8l28et"] + +[ext_resource type="Script" uid="uid://dtc8338f82g3n" path="res://scene/ground/script/c03/s01_closeup_demo公告.gd" id="1_emo0y"] +[ext_resource type="Texture2D" uid="uid://0quk16rj31cm" path="res://asset/art/scene/demo额外/demo感谢告示.png" id="2_qgsol"] +[ext_resource type="FontFile" uid="uid://255whp7fuig5" path="res://asset/font/字体/三极行楷简体-粗.ttf" id="3_emo0y"] +[ext_resource type="FontVariation" uid="uid://1ryw42kej6lv" path="res://config/font_ui.tres" id="3_qgsol"] +[ext_resource type="Script" uid="uid://dpocj5al0rvai" path="res://ui/text_helper.gd" id="5_emo0y"] + +[node name="CloseupDemo公告" type="CanvasLayer"] +script = ExtResource("1_emo0y") + +[node name="BG" type="TextureRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 0 + +[node name="遮罩" type="TextureRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = ExtResource("2_qgsol") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 0 +offset_left = 215.0 +offset_top = 58.0 +offset_right = 358.0 +offset_bottom = 257.0 + +[node name="VBoxContainer" type="VBoxContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -65.0 +offset_top = -87.0 +offset_right = 65.0 +offset_bottom = 87.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 10 + +[node name="公告标题" type="Label" parent="Control/VBoxContainer"] +custom_minimum_size = Vector2(130, 0) +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_emo0y") +theme_override_font_sizes/font_size = 13 +text = "感谢试玩" +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 3 +script = ExtResource("5_emo0y") +translation_key = "c02_demo感谢试玩" + +[node name="公告正文" type="Label" parent="Control/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(130, 0) +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_qgsol") +theme_override_font_sizes/font_size = 8 +text = "以上是《衔蝶》demo的全部内容啦,感谢你抽出宝贵的时间体验我们的游戏! +试玩虽然结束,但吕萍的旅程才刚刚开始,后面的故事将更加精彩!你在游戏中探索的每一步都是对我们的鼓励和支持! +在游戏上线前,我们将继续优化游戏内容,完善和打磨游戏设计、叙事流程,音效、画面表现等。 +最后,欢迎你对《衔蝶》的试玩提出反馈,这对我们非常重要!期待与你的下次相遇,再见!" +vertical_alignment = 1 +autowrap_mode = 3 +script = ExtResource("5_emo0y") +translation_key = "c02_demo公告" diff --git a/ui/text_helper.gd b/ui/text_helper.gd new file mode 100644 index 00000000..6d2c47d7 --- /dev/null +++ b/ui/text_helper.gd @@ -0,0 +1,22 @@ +@tool +extends Node + +@export var property_name := "text" +@export var translation_key := "" +@export_tool_button("刷新") var refresh = _refresh.bind(true) + + +func _ready() -> void: + _refresh() + + +# res://asset/dialogue/item_description.zh_CN.translation +var items_translation = preload("uid://c1x5bqwulamey") as Translation + + +func _refresh(from_tool := false): + if property_name and translation_key: + var msg = tr(translation_key) + if from_tool: + msg = items_translation.get_message(translation_key) + set(property_name, msg.replace("
", "\n")) diff --git a/ui/text_helper.gd.uid b/ui/text_helper.gd.uid new file mode 100644 index 00000000..8b6d7bdd --- /dev/null +++ b/ui/text_helper.gd.uid @@ -0,0 +1 @@ +uid://dpocj5al0rvai diff --git a/util/tester.gd b/util/tester.gd new file mode 100644 index 00000000..78c46373 --- /dev/null +++ b/util/tester.gd @@ -0,0 +1,130 @@ +@tool +extends Node + +@export_tool_button("测试") var test = _load_test +@export_tool_button("refresh") var refresh = notify_property_list_changed +var method := "" + + +func _load_test(): + call(method) + + +func _get_property_list() -> Array[Dictionary]: + var method_arr = PackedStringArray() + var method_list = get_method_list() + # build method_arr + for m in method_list: + if ( + not str(m.name).begins_with("_") + and m.name != "get_property_list" + and len(m.args) == 0 + and m.flags == METHOD_FLAGS_DEFAULT + ): + method_arr.append(m.name) + + return [ + { + "name": "method", + "type": TYPE_STRING, + "usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE, + "hint": PROPERTY_HINT_ENUM_SUGGESTION, + "hint_string": ",".join(method_arr) + } + ] + + +func test_map_alias(): + var map := { + "a": 1, + "b": {"b1": 1}, + } + var cow_map := map + map.a = 2 + cow_map.a = 3 + # map before: { "a": 3, "b": { "b1": 1 } } + print("map before: ", map) + # cow_map before: { "a": 3, "b": { "b1": 1 } } + print("cow_map before: ", cow_map) + _foo_map(cow_map) + map.a = 8 + cow_map.a = 9 + # map after: { "a": 9, "b": { "b1": 5 } } + print("map after: ", map) + # cow_map after: { "a": 9, "b": { "b1": 5 } } + print("cow_map after: ", cow_map) + + +func _foo_map(map): + map.a = 5 + map.b.b1 = 5 + + +func test_array_alias(): + var arr := [1, 2] + var cow_arr := arr + arr[0] = 5 + _foo_arr(cow_arr) + # arr: [5, 6, 10, , ] + print("arr: ", arr) + # cow_arr: [5, 6, 10, , ] + print("cow_arr: ", cow_arr) + + +func _foo_arr(arr): + arr[1] = 6 + arr.append(10) + arr.resize(5) + + +func test_concat_arr(): + var arr := [1, 2] + var concat_arr := arr + [] + arr[0] = 5 + _foo_arr(concat_arr) + # arr: [5, 2] + print("arr: ", arr) + # concat_arr: [1, 6, 10, , ] + print("concat_arr: ", concat_arr) + + +func test_packed_array(): + var arr := PackedInt32Array([1, 2]) + var cow_arr := arr + arr[0] = 5 + _foo_arr(cow_arr) + # arr: [5, 6, 10, 0, 0] + print("arr: ", arr) + # cow_arr: [5, 6, 10, 0, 0] + print("cow_arr: ", cow_arr) + + +# func _ready() -> void: +# $Button.mouse_exited.connect(_free_btn) +# _wait_btn() +# get_tree().create_timer(3.0).timeout.connect(_free_self) + + +# func _wait_btn() -> void: +# print("waiting...") +# var res = await _waiting() +# print("button pressed res", res) +# print("hello") + + +# func _waiting() -> void: +# await get_tree().create_timer(1.0).timeout + + +# func _free_btn() -> void: +# print("free button") +# $Button.queue_free() +# print("button freed") + + +# func _free_self() -> void: +# # print("free self") +# # queue_free() +# # print("self freed") +# print("quit") +# get_tree().quit() diff --git a/util/tester.gd.uid b/util/tester.gd.uid new file mode 100644 index 00000000..8ba77f03 --- /dev/null +++ b/util/tester.gd.uid @@ -0,0 +1 @@ +uid://bcb8rlc4mq7cf diff --git a/util/tester.tscn b/util/tester.tscn new file mode 100644 index 00000000..41a6161f --- /dev/null +++ b/util/tester.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=2 format=3 uid="uid://bloqf3417kv0c"] + +[ext_resource type="Script" uid="uid://bcb8rlc4mq7cf" path="res://util/tester.gd" id="1_75mhk"] + +[node name="Tester" type="Node"] +script = ExtResource("1_75mhk") + +[node name="Node2D" type="Node2D" parent="."] + +[node name="Node2D2" type="Node2D" parent="."] + +[node name="Node2D4" type="Node2D" parent="Node2D2"] + +[node name="Node2D3" type="Node2D" parent="."] + +[node name="Button" type="Button" parent="."] +offset_left = 38.0 +offset_top = 29.0 +offset_right = 80.0 +offset_bottom = 49.0 +text = "press me"