shake canvas layer; npc首次交互问号

This commit is contained in:
cakipaul 2025-06-29 22:57:02 +08:00
parent 735592b31f
commit 4cabe3247d
36 changed files with 182 additions and 156 deletions

View File

@ -116,6 +116,7 @@ current_scene 是通过 GroundLoader 加载的,在 ground loader 加载 ground
- Sign 触发机制,图标位置管理
- GroundArchive场景内 namespace 隔离,内部需要保证节点名 unique
- 基础节点InspectableAmbushNoteInteractableCloseupNpc
- [#ban_skip] 与 IGNORE_INPUT : 前者 debug 可跳过,后者总不可跳过
- PropHud 切换与点击展示
- SignSnapper 拉动机制
- ReenterLock 机制

View File

@ -1,4 +1,4 @@
[gd_resource type="SpriteFrames" load_steps=182 format=3 uid="uid://c6okvaeemoodq"]
[gd_resource type="SpriteFrames" load_steps=174 format=3 uid="uid://c6okvaeemoodq"]
[ext_resource type="Texture2D" uid="uid://ciai4wast4i2a" path="res://asset/art/gif/c01_孤儿院围墙/【画画小女孩】回头/0.png" id="1_0n0k8"]
[ext_resource type="Texture2D" uid="uid://pabw11j5ifdw" path="res://asset/art/gif/c01_孤儿院围墙/【画画男孩-2】画画/0.png" id="1_3rkvk"]
@ -139,24 +139,16 @@
[ext_resource type="Texture2D" uid="uid://drya8wfn472so" path="res://asset/art/gif/c01_孤儿院围墙/【站立小孩-2】侧面跑步/3.png" id="82_pnke1"]
[ext_resource type="Texture2D" uid="uid://kgyv3iaorqfu" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】奔跑/6.png" id="82_ssn0q"]
[ext_resource type="Texture2D" uid="uid://c7c515i15ld6h" path="res://asset/art/gif/c01_孤儿院围墙/【站立小孩-2】侧面跑步/4.png" id="83_6vlkr"]
[ext_resource type="Texture2D" uid="uid://65kd4xdppy1q" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/0.png" id="83_fb61f"]
[ext_resource type="Texture2D" uid="uid://bl62sfnedwjy8" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/0.png" id="83_qm1pv"]
[ext_resource type="Texture2D" uid="uid://dxf66pyrn72mu" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/1.png" id="84_8wswo"]
[ext_resource type="Texture2D" uid="uid://tolckwwswgfo" path="res://asset/art/gif/c01_孤儿院围墙/【站立小孩-2】侧面跑步/5.png" id="84_eo5tp"]
[ext_resource type="Texture2D" uid="uid://bna3mk142wj61" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/1.png" id="84_hodev"]
[ext_resource type="Texture2D" uid="uid://dkxmfjjcrh15n" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/2.png" id="85_br80e"]
[ext_resource type="Texture2D" uid="uid://do4twfud47big" path="res://asset/art/gif/c01_孤儿院围墙/【站立小孩-2】侧面跑步/6.png" id="85_kwto3"]
[ext_resource type="Texture2D" uid="uid://dx6wr0efie846" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/2.png" id="85_w78wp"]
[ext_resource type="Texture2D" uid="uid://ctnhd5n21kotj" path="res://asset/art/gif/c01_孤儿院围墙/【站立小孩-2】侧面跑步/7.png" id="86_0xyu3"]
[ext_resource type="Texture2D" uid="uid://bvhv757upma3y" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/3.png" id="86_84780"]
[ext_resource type="Texture2D" uid="uid://b7afvmbocjhte" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/3.png" id="86_yxj1c"]
[ext_resource type="Texture2D" uid="uid://d4ni87qy7dku7" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/4.png" id="87_liy3k"]
[ext_resource type="Texture2D" uid="uid://b1klwki8rtqko" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/4.png" id="87_wb7lj"]
[ext_resource type="Texture2D" uid="uid://b7cc45pyik8sp" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/5.png" id="88_eff0s"]
[ext_resource type="Texture2D" uid="uid://cwnr7kfb6m3t1" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/5.png" id="88_iasis"]
[ext_resource type="Texture2D" uid="uid://8l0swi37h7jh" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/6.png" id="89_kkuwn"]
[ext_resource type="Texture2D" uid="uid://d3wrowwavogar" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/6.png" id="89_x8yr1"]
[ext_resource type="Texture2D" uid="uid://cfgk00olwskfw" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/7.png" id="90_jh438"]
[ext_resource type="Texture2D" uid="uid://b7qtfebqtvuj" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/7.png" id="90_vjtvq"]
[ext_resource type="Texture2D" uid="uid://dhemjx6imeo6e" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】画画/8.png" id="91_0iojk"]
[ext_resource type="Texture2D" uid="uid://ddar2xgo7up15" path="res://asset/art/gif/c01_孤儿院围墙/【胖小孩背着残疾小孩】摔倒/8.png" id="91_uvs17"]
@ -724,30 +716,6 @@ animations = [{
"speed": 30.0
}, {
"frames": [{
"duration": 3.0,
"texture": ExtResource("83_fb61f")
}, {
"duration": 3.0,
"texture": ExtResource("84_8wswo")
}, {
"duration": 3.0,
"texture": ExtResource("85_w78wp")
}, {
"duration": 30.0,
"texture": ExtResource("86_yxj1c")
}, {
"duration": 6.0,
"texture": ExtResource("87_liy3k")
}, {
"duration": 6.0,
"texture": ExtResource("88_eff0s")
}, {
"duration": 6.0,
"texture": ExtResource("89_x8yr1")
}, {
"duration": 6.0,
"texture": ExtResource("90_jh438")
}, {
"duration": 6.0,
"texture": ExtResource("91_uvs17")
}, {

View File

@ -175,6 +175,7 @@ c02_一楼戏台,盖着布的木头架子...用来做什么的呢,,,,,
c02_描述垃圾通道,桶是空的,飘着一股血气,又酸又腥。,,,,,
c02_一楼疯子互动后,这人有点不正常...最好离他远点。,,,,,
c02_一楼粘鼠板,这里原来放着什么?,,,,,
c02_一楼死老鼠,老鼠被粘住死掉了。,,,,,
c02_获得小猫玩具,小猫玩具亮起来了,这光...竟有一丝暖意,,,,,
c02_敲门_肉掉落,楼道有东西掉下来了?,,,,,
c02_敲门_老鼠叼肉,刚刚这里有块肉不见了?,,,,,

1 keys zh_CN _character _notes _tags zh_SH en
175 c02_描述垃圾通道 桶是空的,飘着一股血气,又酸又腥。
176 c02_一楼疯子互动后 这人有点不正常...最好离他远点。
177 c02_一楼粘鼠板 这里原来放着什么?
178 c02_一楼死老鼠 老鼠被粘住死掉了。
179 c02_获得小猫玩具 小猫玩具亮起来了,这光...竟有一丝暖意
180 c02_敲门_肉掉落 楼道有东西掉下来了?
181 c02_敲门_老鼠叼肉 刚刚这里有块肉不见了?

View File

@ -209,6 +209,7 @@
桶是空的,飘着一股血气,又酸又腥。 [ID:c02_描述垃圾通道]
这人有点不正常...最好离他远点。 [ID:c02_一楼疯子互动后]
这里原来放着什么? [ID:c02_一楼粘鼠板]
老鼠被粘住死掉了。 [ID:c02_一楼死老鼠]
# c02 小猫玩具
小猫玩具亮起来了,这光...竟有一丝暖意 [ID:c02_获得小猫玩具]
# c02 敲门_老鼠叼肉

View File

@ -93,6 +93,7 @@ func _check_character_runtime_status():
sprite.scale = current_animation_config["scale"]
# editor 中无需检查下列项目
if Engine.is_editor_hint() or not is_node_ready() or SceneManager.is_restarting():
_play_animation()
return
# 如果当前是 prop_小猫玩具完整 ,尝试点亮玩家的灯效;否则无需点亮
if SceneManager.get_current_prop(false) == "prop_小猫玩具完整":

View File

@ -32,6 +32,7 @@ signal sign_mark_offset_updated
# 首次进入 tree 就直接启用
@export var on_first_enter_tree := false
@export var cooldown_time := 0.5
@export var lock_player_on_playing_dialogue = true
var hook_animation = ""
@export var hook_os_key := ""
@export_enum("c01", "c02", "c03", "c04", "c05", "c06") var hook_dialogue_res = "c01":
@ -94,9 +95,7 @@ func _ready() -> void:
# 更新 hook_animation 的可选项
if animation_player:
animation_player.animation_libraries_updated.connect(notify_property_list_changed)
# editor 中展示 sign
sign_mark.enabled = true
sign_mark.display_sign = true
_check_sign_status()
return
# setup default value
ground_archive = ArchiveManager.archive.ground_archive()
@ -189,10 +188,12 @@ func _do_trigger():
_check_sign_status()
# hook_dialogue, await to end
if hook_dialogue_title:
SceneManager.lock_player(0.0)
if lock_player_on_playing_dialogue:
SceneManager.lock_player(0.0)
DialogueManager.show_dialogue_balloon(dialogue_res, hook_dialogue_title)
await DialogueManager.dialogue_ended
SceneManager.unlock_player()
if lock_player_on_playing_dialogue:
SceneManager.unlock_player()
func _get(property: StringName) -> Variant:

View File

@ -18,6 +18,7 @@ hook_method = ""
[node name="Sign" parent="." instance=ExtResource("2_n51wc")]
unique_name_in_owner = true
display_sign = false
[node name="Area2D" type="Area2D" parent="."]
unique_name_in_owner = true

View File

@ -5,7 +5,7 @@ class_name BgmControl extends Node
@export var bgm_stream: AudioStream
@export var db := 0.0
@export var stop_ease_duration := 3.0
@export var stop_on_ground_ease_out := false
func _ready() -> void:
if not bgm_title:

View File

@ -11,12 +11,23 @@ signal interacted
set(val):
enabled = val
if is_node_ready():
_align_enabled_status()
@export var height := 60.0:
_align_signs_status()
@export var sign_mark_height := 10.0:
set(val):
height = val
sign_mark_height = val
if is_node_ready():
speaking_sign.position.y = -height
sign_mark.sign_mark_offset.y = -sign_mark_height
@export var speaking_sign_height := 60.0:
set(val):
speaking_sign_height = val
if is_node_ready():
speaking_sign.position.y = -speaking_sign_height
@export var sign_x_offset := 0.0:
set(val):
sign_x_offset = val
if is_node_ready():
speaking_sign.position.x = sign_x_offset
sign_mark.position.x = sign_x_offset
@export var collision_width_and_x := Vector2(20.0, 0):
set(val):
collision_width_and_x = val
@ -30,6 +41,14 @@ signal interacted
@onready var sign_snapper = %SignSnapper as SignSnapper
@onready var area2d = %Area2D as Area2D
var ground_archive: GroundArchive
# 尝试互动的次数
var icount: int:
set(val):
icount = val
ground_archive.set_pair(name, "icount", val)
_align_signs_status()
var dialogue_title := ""
var dialogue_res = preload("res://asset/dialogue/npc.dialogue")
@ -38,7 +57,12 @@ var base_mod := Color.WHITE_SMOKE
func _ready() -> void:
speaking_sign.position.y = -height
# sign position
sign_mark.sign_mark_offset.y = -sign_mark_height
speaking_sign.position.y = -speaking_sign_height
sign_mark.position.x = sign_x_offset
speaking_sign.position.x = sign_x_offset
# collisiong shape
var shape = area2d.get_node("CollisionShape2D").shape
shape.size.x = collision_width_and_x.x
area2d.position.x = collision_width_and_x.y
@ -46,68 +70,58 @@ func _ready() -> void:
sign_snapper.radius = walk_to_edge_width
sign_snapper.enabled = snap_to_edge
if Engine.is_editor_hint():
# editor 直接展
# editor 下都显
speaking_sign.visible = true
speaking_sign.modulate.a = 1.0
speaking_sign.modulate.a = 1
speaking_sign.get_node("Sprite2D").position.x = -60.0
speaking_sign.get_node("Sprite2D").frame = 2
sign_mark.display_sign = true
return
# setup default value
ground_archive = ArchiveManager.archive.ground_archive()
icount = ground_archive.get_value(name, "icount", 0)
# 默认为 0
speaking_sign.modulate.a = 0.0
base_scale = speaking_sign.scale
base_mod = speaking_sign.modulate
area2d.body_entered.connect(_on_entered)
area2d.body_exited.connect(_on_exited)
if snap_to_edge:
sign_snapper.arrived.connect(_on_interacted)
else:
sign_mark.interacted.connect(_on_interacted)
# sign_mark.cancel.connect(_stop_speaking)
sign_mark.toggle_active.connect(_on_toggle_active)
_align_enabled_status()
visibility_changed.connect(_on_visibility_changed)
if sprite_frames and animation:
play()
func _on_visibility_changed() -> void:
_align_enabled_status()
_align_signs_status()
func _align_enabled_status():
speaking_sign.visible = enabled
func _align_signs_status():
sign_mark.enabled = enabled
func _on_entered(_body = null) -> void:
var tween = create_tween()
tween.tween_property(speaking_sign, "modulate:a", 1.0, 0.5)
func _on_exited(_body = null) -> void:
var tween = create_tween()
tween.tween_property(speaking_sign, "modulate:a", 0.0, 0.5)
sign_mark.display_sign = icount == 0
speaking_sign.visible = enabled and icount > 0
func _on_toggle_active(activated: bool) -> void:
if activated:
_play_speaking()
else:
_stop_speaking()
var speaking := false
speaking_animation.play("speaking")
# icount 影响 visible; activated 影响 modulate
speaking_sign.modulate.a = 1 if activated else 0
func _on_interacted() -> void:
if speaking:
return
# play dialogue
if dialogue_title:
interacted.emit()
DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title)
speaking = true
if GlobalConfig.DEBUG:
print("[" + name + "] call lock")
SceneManager.lock_player(0, action_key)
icount += 1
ground_archive.set_pair(name, "icount", icount)
DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title)
interacted.emit()
var tween = create_tween()
tween.tween_property(speaking_sign, "modulate", Color.WHITE, 0.5)
tween.parallel().tween_property(speaking_sign, "scale", base_scale * 1.3, 0.3)
@ -118,15 +132,6 @@ func _on_interacted() -> void:
if GlobalConfig.DEBUG:
print("[" + name + "] call lock")
SceneManager.unlock_player()
speaking = false
func _play_speaking() -> void:
speaking_animation.play("speaking")
func _stop_speaking() -> void:
speaking_animation.play("RESET")
func _get(property: StringName) -> Variant:

View File

@ -35,18 +35,6 @@ tracks/1/keys = {
"update": 1,
"values": [0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("SpeakingSign2D:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_a386j"]
resource_name = "speaking"
@ -77,18 +65,6 @@ tracks/1/keys = {
"update": 2,
"values": [0, 2]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("SpeakingSign2D:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_pjqf1"]
_data = {
@ -140,9 +116,7 @@ script = ExtResource("4_j5svs")
[node name="Sign" parent="." instance=ExtResource("4_nokx4")]
unique_name_in_owner = true
offset_top = -60.0
offset_bottom = -60.0
display_sign = false
sign_mark_offset = Vector2(0, -60)
[node name="SpeakingAnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
@ -160,7 +134,6 @@ texture = SubResource("GradientTexture2D_7lwt5")
[node name="SpeakingSign2D" type="Node2D" parent="."]
unique_name_in_owner = true
visible = false
modulate = Color(0.753984, 0.753984, 0.753984, 1)
z_index = 100
position = Vector2(0, -60)
@ -168,6 +141,7 @@ scale = Vector2(0.07, 0.07)
[node name="Sprite2D" type="AnimatedSprite2D" parent="SpeakingSign2D"]
light_mask = 16
position = Vector2(60, 0)
sprite_frames = SubResource("SpriteFrames_k7dca")
offset = Vector2(60, 0)

View File

@ -174,10 +174,10 @@ func _do_transition(scene_name: String) -> void:
ground.process_mode = Node.PROCESS_MODE_DISABLED
print("GroundLoader not _allow_ground_start: frozen (delayed)")
_frozen_start_time_ms = Time.get_ticks_msec()
else:
_add_ground()
if _allow_ground_start:
# 如果不阻塞,直接 ground_start 信号
SceneManager.ground_start.emit(ground)
_add_ground()
# 预先加载邻居场景
_post_transition()
if GlobalConfig.DEBUG and not Engine.is_editor_hint():

View File

@ -56,6 +56,10 @@ func _on_ground_ready() -> void:
pass
func _on_ground_start() -> void:
pass
func _on_ready() -> void:
if Engine.is_editor_hint():
return

View File

@ -754,6 +754,7 @@ unique_name_in_owner = true
position = Vector2(270, 23.5)
texture = ExtResource("12_jtglg")
trigger_mode = "interact"
lock_player_on_playing_dialogue = null
hook_animation = "使用鸡毛掸子"
hook_method = "lock_on_use_stick"

View File

@ -223,12 +223,14 @@ note_key = "c01_s06_小朋友房间"
[node name="门口对话ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("11_tudob")]
position = Vector2(295, 43)
cooldown_time = 1.0
lock_player_on_playing_dialogue = false
hook_dialogue_title = "c01_s06_走廊前对话"
[node name="门口ambush" parent="Ground/DeployLayer" index="5" instance=ExtResource("11_tudob")]
position = Vector2(308, 43)
one_shot = false
cooldown_time = 3.0
lock_player_on_playing_dialogue = null
hook_animation = "门口_观望"
[node name="踢球男孩" parent="Ground/DeployLayer" index="6" instance=ExtResource("5_erliv")]
@ -423,6 +425,7 @@ move_configs = Array[Dictionary]([{
position = Vector2(1, 65)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "obstacles_ambush1_triggered"
[node name="Area2D" parent="Ground/DeployLayer/【站立小孩-1】/桌椅ambush1" index="1"]
@ -437,6 +440,9 @@ enabled = false
one_shot = false
hook_method = "game_restart"
[node name="Sign" parent="Ground/DeployLayer/【站立小孩-1】/猫鼠游戏重置ambush" index="0"]
enabled = false
[node name="CollisionShape2D" parent="Ground/DeployLayer/【站立小孩-1】/猫鼠游戏重置ambush/Area2D" index="0"]
shape = SubResource("RectangleShape2D_7cdhx")
@ -485,6 +491,7 @@ position = Vector2(78, 43)
position = Vector2(1, 65)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "obstacles_ambush2_triggered"
[node name="Area2D" parent="Ground/DeployLayer/【站立小孩-2】/桌椅ambush2" index="1"]
@ -498,6 +505,7 @@ position = Vector2(2, 39)
sign_mark_offset = Vector2(0, -3.86)
trigger_mode = "interact"
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_dialogue_title = "c01_s06_四个小孩_对话2"
hook_method = "talk2"
@ -526,13 +534,14 @@ bus = &"game_sfx"
position = Vector2(1809, 56)
one_shot = false
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "game_intro"
[node name="【胖小孩背着残疾小孩】" parent="Ground/DeployLayer" index="18" instance=ExtResource("8_ouldg")]
z_index = 1
position = Vector2(1733, 5)
sprite_frames = ExtResource("7_dsj2r")
animation = &"【胖小孩背着残疾小孩】呼吸"
animation = &"【胖小孩背着残疾小孩】画画"
action_configs = Array[Dictionary]([{
"animation_intro": "【胖小孩背着残疾小孩】呼吸",
"animation_next": "【胖小孩背着残疾小孩】画画",
@ -566,6 +575,7 @@ move_configs = Array[Dictionary]([{
position = Vector2(1, 65)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "obstacles_ambush3_triggered"
[node name="Area2D" parent="Ground/DeployLayer/【胖小孩背着残疾小孩】/桌椅ambush3" index="1"]
@ -586,7 +596,7 @@ move_configs = Array[Dictionary]([{
"animation_next": "",
"duration": 1e+07,
"movement_x": 0.0,
"velocity": Vector2(130, 0)
"velocity": Vector2(120, 0)
}])
[node name="【墙上小孩猫影子】" parent="Ground/DeployLayer/【胖小孩背着残疾小孩】/【单残疾小孩】" instance=ExtResource("8_ouldg")]
@ -611,6 +621,9 @@ position = Vector2(19, 49)
enabled = false
hook_method = "game_failed"
[node name="Sign" parent="Ground/DeployLayer/【胖小孩背着残疾小孩】/【单残疾小孩】/猫鼠游戏失败ambush" index="0"]
enabled = false
[node name="CollisionShape2D" parent="Ground/DeployLayer/【胖小孩背着残疾小孩】/【单残疾小孩】/猫鼠游戏失败ambush/Area2D" index="0"]
shape = SubResource("RectangleShape2D_7cdhx")
@ -625,6 +638,7 @@ hook_method = "talk3"
position = Vector2(4546, 45)
one_shot = false
cooldown_time = 0.1
lock_player_on_playing_dialogue = null
hook_method = "game_succeed"
[node name="Fog" parent="Ground/DeployLayer/猫鼠游戏胜利ambush" instance=ExtResource("14_d5def")]

View File

@ -47,11 +47,11 @@ func _on_ground_ready() -> void:
bookstore_portal.before_pre_transport_wait.connect(_knock_door)
bookstore_portal.get_node("SfxEnter").stream = null
if $"../DeployLayer/其余小孩/Ambush监督小孩".played:
greetings_ambush()
if $"../DeployLayer/Ambush陆仁收刀".played:
holdback_knife()
func greetings_ambush() -> void:
func holdback_knife() -> void:
(luren.sprite_frames as SpriteFrames).set_animation_loop("陆仁舞刀-黄昏带红缨", false)
luren.animation_finished.connect(_on_luren_animation_finished, CONNECT_ONE_SHOT)

View File

@ -181,9 +181,12 @@ sprite_frames = ExtResource("6_thm8f")
animation = &"杂戏团黄昏-推箱子小孩"
autoplay = "杂戏团黄昏-推箱子小孩"
frame_progress = 0.252889
height = -20.0
[node name="陆仁舞刀" parent="Ground/DeployLayer" index="6" instance=ExtResource("9_slaub")]
[node name="Ambush陆仁收刀" parent="Ground/DeployLayer" index="6" instance=ExtResource("9_f61dl")]
position = Vector2(926, 64)
hook_method = "holdback_knife"
[node name="陆仁舞刀" parent="Ground/DeployLayer" index="7" instance=ExtResource("9_slaub")]
position = Vector2(1045, 6)
sprite_frames = ExtResource("6_thm8f")
animation = &"陆仁舞刀-黄昏带红缨"
@ -207,11 +210,12 @@ loop = true
metadata/_custom_type_script = "uid://wapo47a1oddf"
[node name="Npc吉祥话4" parent="Ground/DeployLayer/陆仁舞刀" instance=ExtResource("6_fw22n")]
position = Vector2(-15, 58)
position = Vector2(-22, 51)
enabled = false
speaking_sign_height = 47.0
dialogue_title = "c01_s07_陆仁吉祥话"
[node name="其余小孩" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="7"]
[node name="其余小孩" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="8"]
position = Vector2(1160, 7)
sprite_frames = ExtResource("6_thm8f")
animation = &"杂戏团黄昏-其余小孩"
@ -220,22 +224,28 @@ autoplay = "杂戏团黄昏-其余小孩"
[node name="Ambush监督小孩" parent="Ground/DeployLayer/其余小孩" instance=ExtResource("9_f61dl")]
position = Vector2(-688, 53)
cooldown_time = 0.1
lock_player_on_playing_dialogue = false
hook_dialogue_title = "c01_s07_监督小孩吉祥话"
hook_method = "greetings_ambush"
[node name="Npc吉祥话1" parent="Ground/DeployLayer/其余小孩" instance=ExtResource("6_fw22n")]
position = Vector2(-44, 78)
sign_mark_height = 23.0
speaking_sign_height = 56.0
dialogue_title = "c01_s07_小孩吉祥话1"
[node name="Npc吉祥话2" parent="Ground/DeployLayer/其余小孩" instance=ExtResource("6_fw22n")]
position = Vector2(23, 78)
sign_mark_height = 23.0
speaking_sign_height = 58.0
dialogue_title = "c01_s07_小孩吉祥话2"
[node name="Npc吉祥话3" parent="Ground/DeployLayer/其余小孩" instance=ExtResource("6_fw22n")]
position = Vector2(80, 59)
sign_mark_height = 11.0
speaking_sign_height = 54.0
dialogue_title = "c01_s07_小孩吉祥话3"
[node name="举碗小孩" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="8"]
[node name="举碗小孩" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="9"]
position = Vector2(1297, 7)
sprite_frames = ExtResource("6_thm8f")
animation = &"杂戏团黄昏_举碗小孩"
@ -246,7 +256,7 @@ position = Vector2(6, 57)
title_filter = "c01"
note_key = "c01_s07_钱碗"
[node name="报童" parent="Ground/DeployLayer" index="9" instance=ExtResource("9_slaub")]
[node name="报童" parent="Ground/DeployLayer" index="10" instance=ExtResource("9_slaub")]
position = Vector2(2080, 6)
sprite_frames = ExtResource("6_thm8f")
animation = &"报童待机"
@ -264,7 +274,7 @@ trigger_mode = "interact"
cooldown_time = 1.0
hook_method = "seller_interacted"
[node name="Note橱柜" parent="Ground/DeployLayer" index="10" instance=ExtResource("5_3pha1")]
[node name="Note橱柜" parent="Ground/DeployLayer" index="11" instance=ExtResource("5_3pha1")]
position = Vector2(1681, 32)
action = 5
title_filter = "c01"

View File

@ -131,6 +131,7 @@ texture = ExtResource("5_tnrke")
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "play_shelf_game"
[node name="Interactable信件书桌" parent="Ground/DeployLayer" index="3" instance=ExtResource("7_fue0t")]
@ -174,6 +175,7 @@ position = Vector2(537, 21)
enabled = false
trigger_mode = "interact"
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "pay_off_wage"
[node name="老板" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="8"]

View File

@ -148,6 +148,7 @@ position = Vector2(-119, 13)
position = Vector2(96, 20)
one_shot = false
cooldown_time = 0.1
lock_player_on_playing_dialogue = null
hook_method = "player_been_passed"
[node name="脚步声2D" type="AudioStreamPlayer2D" parent="Ground/DeployLayer/Ghost"]

View File

@ -218,36 +218,42 @@ position = Vector2(1365, 4)
trigger_mode = "area_enter"
one_shot = false
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "pop_title_1"
[node name="ambush_title2" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_3k8jj")]
position = Vector2(2870, -10)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "pop_title_2"
[node name="ambush_title3" parent="Ground/DeployLayer" index="6" instance=ExtResource("6_3k8jj")]
position = Vector2(6341, 3)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "pop_title_3"
[node name="ambush_dialog2" parent="Ground/DeployLayer" index="7" instance=ExtResource("6_3k8jj")]
position = Vector2(866, 5)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "dialog2"
[node name="ambush_dialog3" parent="Ground/DeployLayer" index="8" instance=ExtResource("6_3k8jj")]
position = Vector2(3448, -8)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "dialog3"
[node name="ambush_dialog4" parent="Ground/DeployLayer" index="9" instance=ExtResource("6_3k8jj")]
position = Vector2(5305, -2)
trigger_mode = "area_enter"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "dialog4"
[node name="路灯序列1" type="Node2D" parent="Ground/AmbientLayer" index="0"]

View File

@ -159,6 +159,7 @@ position = Vector2(1127, 28)
enabled = false
one_shot = false
cooldown_time = 0.1
lock_player_on_playing_dialogue = null
hook_method = "player_been_catched"
[node name="脚步声2D" type="AudioStreamPlayer2D" parent="Ground/DeployLayer/Ghost"]
@ -226,6 +227,7 @@ action_configs = Array[Dictionary]([{
[node name="Ambush举碗小孩" parent="Ground/DeployLayer/举碗小孩" instance=ExtResource("9_nqlku")]
position = Vector2(0, 53)
trigger_mode = "interact"
lock_player_on_playing_dialogue = null
hook_method = "ambush_begger_interacted"
[node name="Interactable碗" parent="Ground/DeployLayer/举碗小孩" instance=ExtResource("5_6jrnc")]
@ -247,6 +249,7 @@ position = Vector2(0, 92)
enabled = false
one_shot = false
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "player_run_away"
[node name="Light" parent="Ground/AmbientLayer" index="0" instance=ExtResource("5_kywnm")]

View File

@ -111,6 +111,7 @@ frame_progress = 1.0
[node name="Ambush太暗了" parent="Ground/DeployLayer" index="4" instance=ExtResource("8_52as8")]
position = Vector2(177, 42)
lock_player_on_playing_dialogue = null
hook_os_key = "c02_太暗了"
[node name="海报1" parent="Ground/DeployLayer" index="5" instance=ExtResource("12_0fckv")]
@ -147,6 +148,7 @@ enabled = false
trigger_mode = "interact"
one_shot = false
cooldown_time = 0.0
lock_player_on_playing_dialogue = null
[node name="wall" type="StaticBody2D" parent="Ground/DeployLayer/Ambush纸人"]
position = Vector2(3, 4)
@ -169,6 +171,7 @@ position = Vector2(358, 50)
trigger_mode = "interact"
collision_width_and_x = Vector2(23.86, 0)
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "lumber_interacted"
[node name="杂物眨眼睛" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="11"]
@ -210,6 +213,7 @@ mute_when_interacted = true
position = Vector2(525, 61)
one_shot = false
cooldown_time = 1.0
lock_player_on_playing_dialogue = null
hook_method = "check_if_show_shoes"
[node name="煤油灯" parent="Ground/DeployLayer" index="17" instance=ExtResource("17_mpkj1")]
@ -230,6 +234,7 @@ texture = ExtResource("22_jg8g0")
[node name="Ambush小蝉闪现" parent="Ground/DeployLayer" index="19" instance=ExtResource("8_52as8")]
position = Vector2(388, 47)
lock_player_on_playing_dialogue = null
hook_method = "xiaochan_disappear"
[node name="小蝉" type="AnimatedSprite2D" parent="Ground/DeployLayer/Ambush小蝉闪现"]

View File

@ -481,6 +481,7 @@ visible = false
[node name="Ambush闷雷纸人" parent="Ground/DeployLayer/闷雷_纸人闪现" instance=ExtResource("25_iyaiw")]
position = Vector2(1353, 33)
lock_player_on_playing_dialogue = null
hook_method = "shocking_lighting"
[node name="排队常人" type="Sprite2D" parent="Ground/DeployLayer/闷雷_纸人闪现"]
@ -505,6 +506,7 @@ texture = SubResource("GradientTexture2D_3nako")
[node name="Ambush要下雨了" parent="Ground/DeployLayer" index="12" instance=ExtResource("25_iyaiw")]
position = Vector2(1611, 46)
lock_player_on_playing_dialogue = null
hook_os_key = "c02_院子_要下雨"
[node name="Pickable小鞋子" parent="Ground/DeployLayer" index="13" instance=ExtResource("7_em2ma")]
@ -610,12 +612,14 @@ action_key = 3
[node name="Ambush惊悚闪电" parent="Ground/DeployLayer" index="24" instance=ExtResource("25_iyaiw")]
position = Vector2(1319, 40)
lock_player_on_playing_dialogue = null
hook_method = "shocking_lighting"
[node name="Ambush偷听对话" parent="Ground/DeployLayer" index="25" instance=ExtResource("25_iyaiw")]
position = Vector2(1836, 7)
trigger_mode = "interact"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "eavesdrop"
[node name="李氏赖子房间人影" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="26"]
@ -632,7 +636,8 @@ animation = &"疯子看井"
frame_progress = 0.298829
snap_to_edge = false
action_key = 3
height = 49.11
sign_mark_height = 11.0
speaking_sign_height = 55.0
collision_width_and_x = Vector2(37.08, 0)
dialogue_title = "c02_s11_井边疯子对话"
@ -653,6 +658,7 @@ position = Vector2(2154, 60)
position = Vector2(-185, -10)
enabled = false
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "bully_ambush"
[node name="小蝉" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")]
@ -699,6 +705,7 @@ position = Vector2(-116, -13)
enabled = false
one_shot = false
cooldown_time = 4.0
lock_player_on_playing_dialogue = null
hook_method = "block_right_move"
[node name="wall" type="StaticBody2D" parent="Ground/DeployLayer/霸凌"]
@ -916,6 +923,7 @@ sign_mark_offset = Vector2(13.57, -39.84)
enabled = false
trigger_mode = "interact"
one_shot = false
lock_player_on_playing_dialogue = null
[node name="小婵呼吸" type="AnimatedSprite2D" parent="Ground/DeployLayer/火灾/Ambush等待的小蝉"]
z_index = 9

View File

@ -13,9 +13,6 @@ func _ready() -> void:
return
var pick_meat_amush_allowed = false
func _on_ground_ready() -> void:
# 粘鼠游戏
if ArchiveManager.get_global_value(&"c02_meat_dropping"):
@ -27,9 +24,11 @@ func _on_ground_ready() -> void:
sprite.play()
else:
$"../DeployLayer/Interactable粘鼠板/粘鼠死亡".visible = true
$"../DeployLayer/Interactable粘鼠板/Note死老鼠".enabled = true
ArchiveManager.set_global_entry(&"c02_meat_given", true)
else:
pick_meat_amush_allowed = true
$"../DeployLayer/Ambush老鼠叼肉".enabled = true
$"../DeployLayer/老鼠叼肉".visible = true
if ArchiveManager.get_global_value(&"c02_meat_given"):
$"../DeployLayer/Pickable掉落的肉".enabled = true
@ -48,14 +47,11 @@ func _on_ground_ready() -> void:
# 老鼠叼肉 ambush
func mouse_pick_meat() -> void:
if not pick_meat_amush_allowed:
return
pick_meat_amush_allowed = false
$"../DeployLayer/Ambush老鼠叼肉".enabled = false
SceneManager.freeze_player(2.0)
# 标记为已掉落
ArchiveManager.set_global_entry(&"c02_meat_dropping", false)
var sprite = $"../DeployLayer/老鼠叼肉"
sprite.visible = true
sprite.play()
await sprite.animation_finished
SceneManager.pop_os_with_str("c02_敲门_老鼠叼肉")

View File

@ -150,7 +150,8 @@ sprite_frames = ExtResource("7_mrltr")
animation = &"疯子坐姿"
autoplay = "疯子坐姿"
frame_progress = 0.539486
height = 25.0
sign_mark_height = 25.0
speaking_sign_height = 25.0
dialogue_title = "c02_疯子_01"
[node name="PointLight2D2" type="PointLight2D" parent="Ground/DeployLayer/Npc疯子"]
@ -163,6 +164,7 @@ texture = SubResource("GradientTexture2D_2yvhw")
position = Vector2(177, 50)
enabled = false
trigger_mode = "interact"
lock_player_on_playing_dialogue = null
hook_method = "wood_puppet"
[node name="火苗" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="5"]
@ -241,9 +243,16 @@ position = Vector2(0, 5)
sprite_frames = ExtResource("17_bk7rf")
animation = &"老鼠被黏住死亡"
[node name="Note死老鼠" parent="Ground/DeployLayer/Interactable粘鼠板" instance=ExtResource("10_8t4w6")]
enabled = false
title_filter = "c02"
note_key = "c02_一楼死老鼠"
[node name="Ambush老鼠叼肉" parent="Ground/DeployLayer" index="11" instance=ExtResource("8_rcuxq")]
position = Vector2(585, 80)
enabled = false
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "mouse_pick_meat"
[node name="老鼠叼肉" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="12"]
@ -279,6 +288,7 @@ visible = false
visibility_layer = 5
position = Vector2(394, 53)
enabled = false
lock_player_on_playing_dialogue = null
hook_method = "xiaochan_disappear"
[node name="ProSprite" parent="Ground/DeployLayer/Ambush小蝉消失" instance=ExtResource("22_heq1x")]
@ -320,6 +330,7 @@ texture = ExtResource("8_tueh3")
points = PackedVector2Array(23, 150, 700, 150)
[node name="DirectionalLight2D" parent="Ground" index="8"]
visible = false
energy = 0.9
blend_mode = 1

View File

@ -956,7 +956,7 @@ gaslight_energy = 2.0
ground_height_offset = 15.0
[node name="Interactable老鼠洞" parent="Ground/DeployLayer" index="9" instance=ExtResource("7_0d746")]
position = Vector2(610, 50)
position = Vector2(618, 50)
enabled = false
one_shot_max_times = 2
disable_prop_after_interacted = true
@ -967,7 +967,7 @@ prop_key2 = "prop_小鞋子2"
shape = SubResource("RectangleShape2D_7kxvk")
[node name="SignSnapper" parent="Ground/DeployLayer/Interactable老鼠洞" index="4"]
radius = 15.0
radius = 20.0
walk_to_edge = true
[node name="小老鼠拖鞋子" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="10"]
@ -1005,7 +1005,7 @@ attenuation = 2.0
bus = &"game_sfx"
script = ExtResource("14_7x2h6")
loop = true
loop_round_time = 1.0
loop_round_time = 0.8
metadata/_custom_type_script = "uid://wapo47a1oddf"
[node name="Ambush三男孩" parent="Ground/DeployLayer" index="13" instance=ExtResource("14_k01ve")]
@ -1015,6 +1015,7 @@ enabled = false
trigger_mode = "interact"
one_shot = false
cooldown_time = 0.1
lock_player_on_playing_dialogue = null
hook_method = "boys_ball_game"
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="Ground/DeployLayer/Ambush三男孩"]
@ -1148,6 +1149,7 @@ texture = SubResource("GradientTexture2D_h3h1a")
position = Vector2(553, -5)
texture = ExtResource("37_osg51")
collision_width_and_x = Vector2(150, 0)
lock_player_on_playing_dialogue = null
hook_method = "glimpse_hide_out"
[node name="MainPlayer" parent="Ground" index="5"]
@ -1164,6 +1166,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

View File

@ -221,12 +221,6 @@ animation_low_mode = true
hide_texture = true
gaslight_energy = 2.0
[node name="SfxInvalid" parent="Ground/DeployLayer/灯座Sprite2D/煤油灯" index="0"]
process_mode = 1
[node name="SfxSuccess" parent="Ground/DeployLayer/灯座Sprite2D/煤油灯" index="1"]
process_mode = 1
[node name="CollisionShape2D" parent="Ground/DeployLayer/灯座Sprite2D/煤油灯/Area2D" index="0"]
shape = SubResource("RectangleShape2D_a48k2")
@ -271,6 +265,7 @@ texture_scale = 1.5
position = Vector2(571, 28)
trigger_mode = "interact"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "hole_interacted"
[node name="Sign" parent="Ground/DeployLayer/Ambush偷听" index="0"]
@ -312,6 +307,7 @@ metadata/_custom_type_script = "uid://wapo47a1oddf"
position = Vector2(522, 31)
enabled = false
trigger_mode = "interact"
lock_player_on_playing_dialogue = null
hook_method = "look_back_hole"
[node name="Note十字架" parent="Ground/DeployLayer" index="11" instance=ExtResource("14_1ws4i")]

View File

@ -701,6 +701,7 @@ texture = ExtResource("17_drmtd")
[node name="Ambush老鼠" parent="Ground/DeployLayer" index="11" instance=ExtResource("6_6xql4")]
position = Vector2(3822.5, 60.5)
lock_player_on_playing_dialogue = null
hook_method = "mouse_animation"
[node name="老鼠衔大洋" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="12"]
@ -727,6 +728,7 @@ action_configs = Array[Dictionary]([{
[node name="Ambush剪影指天" parent="Ground/DeployLayer/小床人物" instance=ExtResource("6_6xql4")]
position = Vector2(93, 81)
lock_player_on_playing_dialogue = null
hook_method = "point_to_the_moon"
[node name="黑手" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="15"]

View File

@ -242,6 +242,7 @@ texture = ExtResource("15_e24j0")
[node name="Ambush首次进入血脚印" parent="Ground/DeployLayer" index="13" instance=ExtResource("14_3ftnp")]
position = Vector2(192, 38.4517)
cooldown_time = 0.1
lock_player_on_playing_dialogue = null
hook_method = "first_enter_ambush"
[node name="PointLight2D" type="PointLight2D" parent="Ground/AmbientLayer" index="0"]

View File

@ -72,6 +72,7 @@ texture = ExtResource("6_gge8e")
position = Vector2(214, 11)
trigger_mode = "interact"
one_shot = false
lock_player_on_playing_dialogue = null
hook_method = "knock_light_door"
[node name="Ambush猫咪敲门互动" parent="Ground/DeployLayer" index="5" instance=ExtResource("9_yywsi")]
@ -79,6 +80,7 @@ position = Vector2(103, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="Ambush猫咪敲门互动2" parent="Ground/DeployLayer" index="6" instance=ExtResource("9_yywsi")]
@ -86,6 +88,7 @@ position = Vector2(539, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="Ambush猫咪敲门互动3" parent="Ground/DeployLayer" index="7" instance=ExtResource("9_yywsi")]
@ -93,6 +96,7 @@ position = Vector2(663, 5)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="追猫猪头怪_左侧" parent="Ground/DeployLayer" index="8" instance=ExtResource("10_kmk38")]

View File

@ -49,6 +49,7 @@ position = Vector2(105, 16)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="追猫猪头怪" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_fjtlb")]

View File

@ -52,6 +52,7 @@ position = Vector2(106, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="追猫猪头怪" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_pfgbg")]

View File

@ -44,6 +44,7 @@ position = Vector2(661, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="Ambush猫咪敲门互动3" parent="Ground/DeployLayer" index="3" instance=ExtResource("5_emyx1")]
@ -51,6 +52,7 @@ position = Vector2(538, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="Ambush猫咪敲门互动2" parent="Ground/DeployLayer" index="4" instance=ExtResource("5_emyx1")]
@ -58,6 +60,7 @@ position = Vector2(104, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="Ambush猫咪敲门互动4" parent="Ground/DeployLayer" index="5" instance=ExtResource("5_emyx1")]
@ -65,6 +68,7 @@ position = Vector2(219, 6)
trigger_mode = "interact"
one_shot = false
cooldown_time = 1.5
lock_player_on_playing_dialogue = null
global_method = "c02_cat_play_with_door"
[node name="追猫猪头怪" parent="Ground/DeployLayer" index="6" instance=ExtResource("6_xoyld")]

View File

@ -22,12 +22,7 @@ func play_bgm():
func pre_finished():
# 在 animation player 结束前 1 秒调用
var camera = SceneManager.get_camera_marker()
camera.limit_top -= 20
camera.limit_bottom += 20
camera.limit_left -= 20
camera.limit_right += 20
camera.shake_camera(8.0, 2.0)
CanvasUtil.shake_layer(self, 2.0, 4.0, 15.0)
# debug 模式允许跳过
if GlobalConfig.DEBUG:
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s11_车夫对话1")

View File

@ -121,6 +121,7 @@ texture = ExtResource("4_beln2")
centered = false
[node name="Sfx" type="AudioStreamPlayer" parent="."]
process_mode = 1
stream = ExtResource("5_c13qq")
volume_db = -40.0
bus = &"game_sfx"
@ -128,6 +129,7 @@ script = ExtResource("5_ug335")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="背景音" type="AudioStreamPlayer" parent="."]
process_mode = 1
stream = SubResource("AudioStreamSynchronized_k54st")
bus = &"game_sfx"
script = ExtResource("5_ug335")

View File

@ -32,7 +32,7 @@ func _ready() -> void:
else:
intro()
label.modulate.a = 0
#game_win()
# game_win()
func intro():
@ -245,7 +245,7 @@ func game_win() -> void:
# 0:默认 1:寻找弹珠(老虎钳可以换弹珠) 2:给出弹珠 3:游戏结束
ArchiveManager.set_global_entry(&"c02_ball_game_stage", 3)
%"Sfx结尾小孩跑".play()
SceneManager.get_camera_marker().shake_camera(10, 4, true)
CanvasUtil.shake_layer(self, 2.0)
# 弹珠雨
$BallsFalling.emitting = true
pivot.visible = false

View File

@ -1,11 +1,14 @@
class_name CanvasUtil extends Object
# 晃动节点
static func shake_node(node: CanvasItem, tween: Tween, duration: float, delta := 5.0, fps := 4.0) -> void:
var origin_pos = node.position
static func shake_layer(layer: CanvasLayer, duration: float, delta := 2.0, fps := 20.0) -> void:
var tween = layer.create_tween()
# shake layer's offset
var origin_offset = layer.offset
var count = int(duration * fps)
var delta_t = 1.0 / fps
for i in range(count):
var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta))
tween.tween_property(node, "position", origin_pos + offset, delta_t).set_trans(Tween.TRANS_CUBIC)
tween.tween_property(layer, "offset", origin_offset + offset, delta_t)
# tween back to origin
tween.tween_property(layer, "offset", origin_offset, delta_t)