增加 SignSnapper 节点;优化 demo 细节

This commit is contained in:
cakipaul 2025-06-25 03:36:07 +08:00
parent ee20a5f2d2
commit 30e435c571
21 changed files with 250 additions and 110 deletions

View File

@ -131,7 +131,7 @@ animations = [{
}], }],
"loop": true, "loop": true,
"name": &"一起牵手跑步", "name": &"一起牵手跑步",
"speed": 30.0 "speed": 6.0
}, { }, {
"frames": [{ "frames": [{
"duration": 9.9, "duration": 9.9,
@ -211,7 +211,7 @@ animations = [{
"duration": 9.9, "duration": 9.9,
"texture": ExtResource("744_6ix4r") "texture": ExtResource("744_6ix4r")
}], }],
"loop": true, "loop": false,
"name": &"小婵牵手动作", "name": &"小婵牵手动作",
"speed": 30.0 "speed": 30.0
}, { }, {

View File

@ -13,12 +13,14 @@ signal exit(arg)
var current_child: Node var current_child: Node
@onready var sign_snapper = %SignSnapper as SignSnapper
func _ready() -> void: func _ready() -> void:
super._ready() super._ready()
if Engine.is_editor_hint(): if Engine.is_editor_hint():
return return
interacted.connect(_close_up_interacted) # interacted.connect(_close_up_interacted)
sign_snapper.arrived.connect(_close_up_interacted)
func _close_up_interacted() -> void: func _close_up_interacted() -> void:

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://dqkxiqbq83cmq"] [gd_scene load_steps=9 format=3 uid="uid://dqkxiqbq83cmq"]
[ext_resource type="Script" uid="uid://bg8q1leel3kx2" path="res://scene/entity/closeup.gd" id="1_tvfr1"] [ext_resource type="Script" uid="uid://bg8q1leel3kx2" path="res://scene/entity/closeup.gd" id="1_tvfr1"]
[ext_resource type="Texture2D" uid="uid://dtyg0nugb2tnf" path="res://asset/art/ui/action_mark/UI探索.png" id="2_dnubm"] [ext_resource type="Texture2D" uid="uid://dtyg0nugb2tnf" path="res://asset/art/ui/action_mark/UI探索.png" id="2_dnubm"]
@ -6,10 +6,11 @@
[ext_resource type="Texture2D" uid="uid://gui0ubwlwoi0" path="res://asset/art/ui/action_mark/UI手.png" id="4_18yy2"] [ext_resource type="Texture2D" uid="uid://gui0ubwlwoi0" path="res://asset/art/ui/action_mark/UI手.png" id="4_18yy2"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_dnubm"] [ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_dnubm"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="5_dnubm"] [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="5_dnubm"]
[ext_resource type="Script" uid="uid://cnt01hiw52bmn" path="res://scene/entity/ux/sign_snapper.gd" id="7_dnubm"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ogin7"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_ogin7"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(10, 70) size = Vector2(40, 70)
[node name="Closeup" type="Sprite2D"] [node name="Closeup" type="Sprite2D"]
script = ExtResource("1_tvfr1") script = ExtResource("1_tvfr1")
@ -39,3 +40,11 @@ collision_layer = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
unique_name_in_owner = true unique_name_in_owner = true
shape = SubResource("RectangleShape2D_ogin7") shape = SubResource("RectangleShape2D_ogin7")
[node name="SignSnapper" type="Marker2D" parent="."]
unique_name_in_owner = true
script = ExtResource("7_dnubm")
release_player_on_arrived = false
radius = 3.0
delay_arrived = 0.3
metadata/_custom_type_script = "uid://cnt01hiw52bmn"

View File

@ -33,6 +33,7 @@ enum { STATUS_NORAML, STATUS_TRANSITIONING, STATUS_INSPECTING_COVER, STATUS_INSP
var content_key: String = "" var content_key: String = ""
@onready var sign_mark = %Sign as Sign @onready var sign_mark = %Sign as Sign
@onready var sign_snapper = %SignSnapper as SignSnapper
@onready var area2d = %Area2D as Area2D @onready var area2d = %Area2D as Area2D
@onready var sfx = %Sfx @onready var sfx = %Sfx
@ -78,7 +79,8 @@ func _ready() -> void:
if content_centered: if content_centered:
content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
sign_mark.interacted.connect(_on_interacted) # sign_mark.interacted.connect(_on_interacted)
sign_snapper.arrived.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel) sign_mark.cancel.connect(_on_cancel)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=11 format=3 uid="uid://ci5anaxsa1apl"] [gd_scene load_steps=12 format=3 uid="uid://ci5anaxsa1apl"]
[ext_resource type="Script" uid="uid://cihyb26hjma4i" path="res://scene/entity/local_inspectable.gd" id="1_85el0"] [ext_resource type="Script" uid="uid://cihyb26hjma4i" path="res://scene/entity/local_inspectable.gd" id="1_85el0"]
[ext_resource type="Texture2D" uid="uid://c0rw25jl762a1" path="res://asset/art/ui/action_mark/UI眼睛.png" id="2_3pauf"] [ext_resource type="Texture2D" uid="uid://c0rw25jl762a1" path="res://asset/art/ui/action_mark/UI眼睛.png" id="2_3pauf"]
@ -9,10 +9,11 @@
[ext_resource type="Texture2D" uid="uid://dwgxa5j6602vv" path="res://asset/art/ui/prop/inspect文本衬底蒙版.png" id="6_q18ff"] [ext_resource type="Texture2D" uid="uid://dwgxa5j6602vv" path="res://asset/art/ui/prop/inspect文本衬底蒙版.png" id="6_q18ff"]
[ext_resource type="FontVariation" uid="uid://1ryw42kej6lv" path="res://config/font_ui.tres" id="7_ianbs"] [ext_resource type="FontVariation" uid="uid://1ryw42kej6lv" path="res://config/font_ui.tres" id="7_ianbs"]
[ext_resource type="Texture2D" uid="uid://f186lvt5y2ql" path="res://asset/art/ui/prop/inspect背景遮罩.png" id="7_xawjo"] [ext_resource type="Texture2D" uid="uid://f186lvt5y2ql" path="res://asset/art/ui/prop/inspect背景遮罩.png" id="7_xawjo"]
[ext_resource type="Script" uid="uid://cnt01hiw52bmn" path="res://scene/entity/ux/sign_snapper.gd" id="10_mtbvd"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(20, 70) size = Vector2(40, 70)
[node name="LocalInspectable" type="Sprite2D"] [node name="LocalInspectable" type="Sprite2D"]
script = ExtResource("1_85el0") script = ExtResource("1_85el0")
@ -123,3 +124,11 @@ theme_override_fonts/font = ExtResource("7_ianbs")
text = "Q: 退出 E: 阅读" text = "Q: 退出 E: 阅读"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="SignSnapper" type="Marker2D" parent="."]
unique_name_in_owner = true
script = ExtResource("10_mtbvd")
release_player_on_arrived = false
radius = 3.0
delay_arrived = 0.3
metadata/_custom_type_script = "uid://cnt01hiw52bmn"

View File

@ -1 +1,62 @@
extends Node @tool
extends Marker2D
class_name SignSnapper
signal arrived
@export var release_player_on_arrived := true
# 仅使用 x 坐标;否则也用 y 进行 walk to
@export var use_x_only := true
# x 左右有效范围
@export_range(0.0, 20.0, 0.1) var radius := 0.0
# arrived 延时
@export_range(0.0, 10.0, 0.1) var delay_arrived := 0.0
@export_tool_button("debug 检查玩家触发位置") var debug_check_player_pos = _debug_check_player_pos
var detacted_sign: Sign
# 玩家在和 sign 交互时,如果读到节点中有 SignSnapper则移动到该位置(x 对齐)
func _ready():
if not get_parent():
return
for c in get_parent().get_children():
if c is Sign:
detacted_sign = c
break
if not detacted_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)
func _on_interacted():
if not detacted_sign:
return
var player = SceneManager.get_player()
var target_pos = global_position
if use_x_only:
target_pos.y = player.global_position.y
var tween = player.walk_to(target_pos, release_player_on_arrived)
if delay_arrived > 0:
tween.tween_interval(delay_arrived)
tween.tween_callback(arrived.emit)
func _debug_check_player_pos():
var ground = EditorInterface.get_edited_scene_root().get_node("Ground") as Ground2D
if use_x_only:
ground.replace_player_to_portal = true
var player = ground.player
if radius > 0:
var player_x = player.global_position.x
if absf(player_x - global_position.x) > radius:
# clamp in range
if player_x < global_position.x:
player.global_position.x = global_position.x - radius
else:
player.global_position.x = global_position.x + radius
else:
player.global_position.x = global_position.x
if not use_x_only:
player.global_position.y = global_position.y

View File

@ -15,6 +15,8 @@ func _on_tab_pressed():
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
# gallery 界面阻塞所有输入事件,除了 escape
get_viewport().set_input_as_handled()
if ( if (
event.is_action_pressed("escape") event.is_action_pressed("escape")
or event.is_action_pressed("cancel") or event.is_action_pressed("cancel")
@ -24,5 +26,7 @@ func _unhandled_input(event: InputEvent) -> void:
var close_stream = preload("res://asset/audio/sfx/交互/收起背包.wav") var close_stream = preload("res://asset/audio/sfx/交互/收起背包.wav")
AudioManager.play_sfx(close_stream) AudioManager.play_sfx(close_stream)
queue_free() queue_free()
# gallery 界面阻塞所有输入事件,除了 escape elif event.is_action_pressed("bag"):
get_viewport().set_input_as_handled() SceneManager.show_bag()
SceneManager.toggle_pause_counter(false)
queue_free()

View File

@ -51,11 +51,11 @@ func _reload_scene(add_to_card:=true):
func _on_toggle_hover(focus: bool): func _on_toggle_hover(focus: bool):
if current_scene and not displaying: if current_scene and not displaying:
if focus: if focus:
grab_focus() scene_btn.grab_focus()
current_scene.run_clip(true) current_scene.run_clip(true)
else: else:
if has_focus(): if scene_btn.has_focus():
release_focus() scene_btn.release_focus()
_reload_scene() _reload_scene()

View File

@ -23,8 +23,7 @@ var default_portal := "left"
if is_node_ready(): if is_node_ready():
move_player_to_portal(default_portal) move_player_to_portal(default_portal)
@export_group("Sound") @export_group("Sound")
@export_enum("none", "ghost", "硬地面", "室外", "crawling", "盒子猫") @export_enum("none", "ghost", "硬地面", "室外", "crawling", "盒子猫") var footstep_type: String = "硬地面":
var footstep_type: String = "硬地面":
set(val): set(val):
footstep_type = val footstep_type = val
if is_node_ready(): if is_node_ready():
@ -57,16 +56,18 @@ const FOOTSTEP_AUDIO = {
var restarting = false var restarting = false
func _enter_tree() -> void: func _enter_tree() -> void:
# 仅在编辑器中调试时,通过 main 场景启动 # 仅在编辑器中调试时,通过 main 场景启动
if GlobalConfig.DEBUG and (not Engine.is_editor_hint()) and (not get_parent() is GroundLoader): if GlobalConfig.DEBUG and (not Engine.is_editor_hint()) and (not get_parent() is GroundLoader):
print("restarting...") print("restarting...")
restarting= true restarting = true
_restart_from_main() _restart_from_main()
return return
if camera_focus_marker: if camera_focus_marker:
camera_focus_marker.enabled = true camera_focus_marker.enabled = true
func _ready() -> void: func _ready() -> void:
if restarting: if restarting:
print("restarting: skip ground _ready()") print("restarting: skip ground _ready()")
@ -145,7 +146,7 @@ func play_footstep_sound() -> void:
func move_player_to_portal(portal_name: String) -> void: func move_player_to_portal(portal_name: String) -> void:
var node_path = NodePath("DeployLayer/portal_" + portal_name) var node_path = NodePath("DeployLayer/portal_" + portal_name)
var portal_node = get_node_or_null(node_path) as Portal2D var portal_node = get_node_or_null(node_path) as Portal2D
if portal_node and player: if portal_node and player:
player.global_position.x = portal_node.global_position.x player.global_position.x = portal_node.global_position.x
@ -161,7 +162,9 @@ func move_player_to_portal(portal_name: String) -> void:
else: else:
printerr("move_player_to_portal player not ready") printerr("move_player_to_portal player not ready")
# 传送后,重置 camera 位置 # 传送后,重置 camera 位置
camera_focus_marker.reset_position_immediately() if not Engine.is_editor_hint():
camera_focus_marker.reset_position_immediately()
func _setup_player_light(): func _setup_player_light():
# 强制显示 directional_light # 强制显示 directional_light

View File

@ -509,7 +509,7 @@ tracks/6/keys = {
"times": PackedFloat32Array(0.08), "times": PackedFloat32Array(0.08),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"values": [{ "values": [{
"args": [Vector2(261, 88), 0.7], "args": [Vector2(261, 88), false],
"method": &"walk_to" "method": &"walk_to"
}] }]
} }

View File

@ -45,23 +45,25 @@ func _on_ground_ready() -> void:
counter.interacted.connect(_on_counter_interacted) counter.interacted.connect(_on_counter_interacted)
if ArchiveManager.get_global_value("c02_counter_pushed_out"): if ArchiveManager.get_global_value("c02_counter_pushed_out"):
counter.visible = true counter.visible = true
var new_bg = $"../DeployLayer/火灾背景"
if not ArchiveManager.get_global_value("c02_burning"): if not ArchiveManager.get_global_value("c02_burning"):
# 点燃前 # 点燃前
counter.enabled = true counter.enabled = true
elif not ArchiveManager.get_global_value("c02_burning_end"): elif ArchiveManager.get_global_value("c02_burning_end"):
# 点燃后~离开前
$"背景音效".switch_stream("火灾")
# 火灾开始后,无需 enable
counter.get_node("点燃").modulate.a = 1.0
new_bg.modulate.a = 1.0
$"../DirectionalLight2D".energy = 0
# 月光
# $"../AmbientLayer/PointLight2D".energy = 0
else:
# 离开后 # 离开后
counter.visible = false counter.visible = false
var new_bg = $"../DeployLayer/火灾背景"
# 点燃后~离开前
if (
ArchiveManager.get_global_value("c02_burning")
and not ArchiveManager.get_global_value("c02_burning_end")
):
new_bg.modulate.a = 1.0
# 火灾开始后,无需 enable
counter.get_node("点燃").modulate.a = 1.0
$"背景音效".switch_stream("火灾")
$"../DirectionalLight2D".energy = 0
madman_npc = $"../DeployLayer/Npc井边疯子" madman_npc = $"../DeployLayer/Npc井边疯子"
# c02_madman_hitwall 之后, c02_ball_game_stage==3游戏结束 之前;同时 eavesdrop_finished # c02_madman_hitwall 之后, c02_ball_game_stage==3游戏结束 之前;同时 eavesdrop_finished
if ( if (
@ -207,6 +209,7 @@ func _setup_bully_or_burning(reenter_scene := false):
bully_layer.get_node("wall/CollisionShape2D").disabled = true bully_layer.get_node("wall/CollisionShape2D").disabled = true
burning_layer.visible = true burning_layer.visible = true
burning_layer.get_node("Ambush等待的小蝉").enabled = true burning_layer.get_node("Ambush等待的小蝉").enabled = true
burning_layer.get_node("Ambush等待的小蝉/SignSnapper").arrived.connect(run_away)
if not reenter_scene: if not reenter_scene:
burning_layer.get_node("Pro小孩喊着火啦3").play() burning_layer.get_node("Pro小孩喊着火啦3").play()
burning_layer.get_node("Pro小孩喊着火啦2").play() burning_layer.get_node("Pro小孩喊着火啦2").play()
@ -289,18 +292,25 @@ func _on_counter_interacted():
func run_away(): func run_away():
SceneManager.pop_debug_dialog_info("美术", "牵手跑开") SceneManager.pop_debug_dialog_info("美术", "牵手跑开")
var player = SceneManager.get_player() var player = SceneManager.get_player()
#TODO 整体修改 # 整体修改
player.visible = false player.visible = false
var ambush_xiaochan = burning_layer.get_node("Ambush等待的小蝉") var ambush_xiaochan = burning_layer.get_node("Ambush等待的小蝉")
ambush_xiaochan.visible = false
ambush_xiaochan.enabled = false ambush_xiaochan.enabled = false
var node = burning_layer.get_node("牵手跑") var node = burning_layer.get_node("牵手跑") as Node2D
node.visible = true var sprite_together = node.get_node("牵手跑动画") as AnimatedSprite2D
SceneManager.get_camera_marker().focus_node(node) sprite_together.visible = true
player.light.reparent(node) SceneManager.get_camera_marker().focus_node(sprite_together)
player.catty_light.reparent(node) player.light.reparent(sprite_together)
play("run_away") player.catty_light.reparent(sprite_together)
# 牵手动作
var sprite_xiaochan = burning_layer.get_node("Ambush等待的小蝉/小婵呼吸")
func run_away_finished(): sprite_together.play("吕萍牵手动作")
sprite_xiaochan.play("小婵牵手动作")
await sprite_together.animation_finished
sprite_xiaochan.visible = false
sprite_together.play("一起牵手跑步")
# 一起跑
var tween = create_tween()
tween.tween_property(node, "global_position:x", 20.0, 18.0)
await tween.finished
SceneManager.get_ground_loader().transition_to_scene("c02_s06", "right") SceneManager.get_ground_loader().transition_to_scene("c02_s06", "right")

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=72 format=3 uid="uid://djc2uaefhmu7"] [gd_scene load_steps=73 format=3 uid="uid://djc2uaefhmu7"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_0dylx"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_0dylx"]
[ext_resource type="Script" uid="uid://dsp5plrdkrsd7" path="res://scene/ground/scene/c02/s03_animation.gd" id="2_dt5aj"] [ext_resource type="Script" uid="uid://dsp5plrdkrsd7" path="res://scene/ground/scene/c02/s03_animation.gd" id="2_dt5aj"]
@ -51,6 +51,7 @@
[ext_resource type="Texture2D" uid="uid://3hruwr03tox1" path="res://asset/art/gif/c02_一楼火灾/7-最左木箱 烧痕.png" id="36_rnk1v"] [ext_resource type="Texture2D" uid="uid://3hruwr03tox1" path="res://asset/art/gif/c02_一楼火灾/7-最左木箱 烧痕.png" id="36_rnk1v"]
[ext_resource type="SpriteFrames" uid="uid://b0icyhxpj16tv" path="res://asset/art/gif/c02_谢幕演出/c02_谢幕演出_frames.tres" id="39_rnk1v"] [ext_resource type="SpriteFrames" uid="uid://b0icyhxpj16tv" path="res://asset/art/gif/c02_谢幕演出/c02_谢幕演出_frames.tres" id="39_rnk1v"]
[ext_resource type="AudioStream" uid="uid://dxoj6vg0wrj0j" path="res://asset/audio/peiyin_new/c02/c02_8小男孩童谣.wav" id="46_qqdxs"] [ext_resource type="AudioStream" uid="uid://dxoj6vg0wrj0j" path="res://asset/audio/peiyin_new/c02/c02_8小男孩童谣.wav" id="46_qqdxs"]
[ext_resource type="Script" uid="uid://cnt01hiw52bmn" path="res://scene/entity/ux/sign_snapper.gd" id="51_vddfx"]
[ext_resource type="Script" uid="uid://wapo47a1oddf" path="res://scene/entity/audio/sfx2d.gd" id="54_o1qbs"] [ext_resource type="Script" uid="uid://wapo47a1oddf" path="res://scene/entity/audio/sfx2d.gd" id="54_o1qbs"]
[sub_resource type="Animation" id="Animation_rt2lh"] [sub_resource type="Animation" id="Animation_rt2lh"]
@ -128,24 +129,6 @@ tracks/1/keys = {
}] }]
} }
[sub_resource type="Animation" id="Animation_1smj8"]
resource_name = "run_away"
length = 20.0
tracks/0/type = "method"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("AnimationPlayer")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(18.5),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"run_away_finished"
}]
}
[sub_resource type="Animation" id="Animation_7ey5t"] [sub_resource type="Animation" id="Animation_7ey5t"]
resource_name = "镜头上下运动" resource_name = "镜头上下运动"
length = 10.0 length = 10.0
@ -181,7 +164,6 @@ _data = {
&"RESET": SubResource("Animation_rt2lh"), &"RESET": SubResource("Animation_rt2lh"),
&"bully": SubResource("Animation_liq0c"), &"bully": SubResource("Animation_liq0c"),
&"eavesdrop": SubResource("Animation_iyaiw"), &"eavesdrop": SubResource("Animation_iyaiw"),
&"run_away": SubResource("Animation_1smj8"),
&"镜头上下运动": SubResource("Animation_7ey5t") &"镜头上下运动": SubResource("Animation_7ey5t")
} }
@ -251,6 +233,9 @@ size = Vector2(10, 50)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1smj8"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_1smj8"]
size = Vector2(250, 50) size = Vector2(250, 50)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vddfx"]
size = Vector2(20, 100)
[sub_resource type="Gradient" id="Gradient_em2ma"] [sub_resource type="Gradient" id="Gradient_em2ma"]
offsets = PackedFloat32Array(0.00928382, 0.681698, 1) offsets = PackedFloat32Array(0.00928382, 0.681698, 1)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0) colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0)
@ -687,7 +672,8 @@ frame_progress = 0.951274
script = ExtResource("34_yy4fp") script = ExtResource("34_yy4fp")
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/右窗"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/右窗"]
position = Vector2(13, 27) position = Vector2(14, 31)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/右窗/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/右窗/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -702,6 +688,7 @@ fade_in = true
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/地面1"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/地面1"]
position = Vector2(26, -20) position = Vector2(26, -20)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/地面1/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/地面1/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -716,6 +703,7 @@ fade_in = true
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/地面2"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/地面2"]
position = Vector2(26, -20) position = Vector2(26, -20)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/地面2/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/地面2/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -730,6 +718,7 @@ fade_in = true
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/地面3"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/地面3"]
position = Vector2(41, -19) position = Vector2(41, -19)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/地面3/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/地面3/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -745,6 +734,7 @@ next_animation = "1-持续"
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域1"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域1"]
position = Vector2(12, 0) position = Vector2(12, 0)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域1/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域1/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -759,6 +749,7 @@ next_animation = "2-持续"
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域2"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域2"]
position = Vector2(37, 41) position = Vector2(37, 41)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域2/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域2/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -773,6 +764,7 @@ next_animation = "3-持续"
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域3"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域3"]
position = Vector2(38, 25) position = Vector2(38, 25)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域3/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域3/Area2D"]
position = Vector2(-50, 9) position = Vector2(-50, 9)
@ -789,6 +781,7 @@ next_animation = "4-持续"
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域4"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域4"]
position = Vector2(12, 17) position = Vector2(12, 17)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域4/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域4/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -803,6 +796,7 @@ next_animation = "5-持续"
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域5"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域5"]
position = Vector2(13, 15) position = Vector2(13, 15)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域5/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域5/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -819,6 +813,7 @@ next_animation = "6-持续"
[node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域6"] [node name="Area2D" type="Area2D" parent="Ground/DeployLayer/火灾/区域6"]
position = Vector2(24, 16) position = Vector2(24, 16)
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域6/Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/区域6/Area2D"]
position = Vector2(-29, 2) position = Vector2(-29, 2)
@ -833,7 +828,6 @@ position = Vector2(66, 54)
texture = ExtResource("36_rnk1v") texture = ExtResource("36_rnk1v")
[node name="Pro小孩发抖" parent="Ground/DeployLayer/火灾" instance=ExtResource("33_ycojw")] [node name="Pro小孩发抖" parent="Ground/DeployLayer/火灾" instance=ExtResource("33_ycojw")]
z_index = 9
position = Vector2(2229, 41) position = Vector2(2229, 41)
sprite_frames = ExtResource("34_1tart") sprite_frames = ExtResource("34_1tart")
animation = &"霸凌3-发抖" animation = &"霸凌3-发抖"
@ -868,29 +862,37 @@ move_configs = Array[Dictionary]([{
}]) }])
[node name="Ambush等待的小蝉" parent="Ground/DeployLayer/火灾" instance=ExtResource("25_iyaiw")] [node name="Ambush等待的小蝉" parent="Ground/DeployLayer/火灾" instance=ExtResource("25_iyaiw")]
position = Vector2(2142, 60) position = Vector2(2142, 71)
sign_mark_offset = Vector2(19.52, 16.49) sign_mark_offset = Vector2(19.04, -38.54)
enabled = false enabled = false
trigger_mode = "interact" trigger_mode = "interact"
one_shot = false one_shot = false
hook_method = "run_away"
[node name="小婵呼吸" type="AnimatedSprite2D" parent="Ground/DeployLayer/火灾/Ambush等待的小蝉"] [node name="小婵呼吸" type="AnimatedSprite2D" parent="Ground/DeployLayer/火灾/Ambush等待的小蝉"]
z_index = 9
position = Vector2(21, -32) position = Vector2(21, -32)
sprite_frames = ExtResource("39_rnk1v") sprite_frames = ExtResource("39_rnk1v")
animation = &"小婵牵手动作" animation = &"小婵呼吸_牵手前"
frame = 5 autoplay = "小婵呼吸_牵手前"
[node name="牵手跑" parent="Ground/DeployLayer/火灾" instance=ExtResource("33_ycojw")] [node name="SignSnapper" type="Marker2D" parent="Ground/DeployLayer/火灾/Ambush等待的小蝉"]
position = Vector2(2150, 30) position = Vector2(-14, 6)
script = ExtResource("51_vddfx")
metadata/_custom_type_script = "uid://cnt01hiw52bmn"
[node name="牵手跑" type="AnimatableBody2D" parent="Ground/DeployLayer/火灾"]
position = Vector2(2133, 46)
collision_layer = 4
[node name="牵手跑动画" parent="Ground/DeployLayer/火灾/牵手跑" instance=ExtResource("33_ycojw")]
visible = false
z_index = 5
position = Vector2(17, -6)
sprite_frames = ExtResource("39_rnk1v") sprite_frames = ExtResource("39_rnk1v")
animation = &"吕萍牵手动作" animation = &"一起牵手跑步"
action_configs = Array[Dictionary]([{
"animation_intro": &"吕萍牵手动作", [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/火灾/牵手跑"]
&"animation_next": "一起牵手跑步", shape = SubResource("RectangleShape2D_vddfx")
"animation_wait_time": 0.0,
"intro_loop": 1
}])
[node name="Interactable柜子" parent="Ground/DeployLayer" index="29" instance=ExtResource("8_xt8j0")] [node name="Interactable柜子" parent="Ground/DeployLayer" index="29" instance=ExtResource("8_xt8j0")]
visible = false visible = false
@ -917,7 +919,7 @@ range_item_cull_mask = 4
texture = SubResource("GradientTexture2D_plfv5") texture = SubResource("GradientTexture2D_plfv5")
[node name="MainPlayer" parent="Ground" index="4"] [node name="MainPlayer" parent="Ground" index="4"]
position = Vector2(25, 93) position = Vector2(2128, 93)
facing_direction = Vector2(1, 0) facing_direction = Vector2(1, 0)
[node name="BGParallaxLayer" parent="Ground/ParallaxForeground" index="0"] [node name="BGParallaxLayer" parent="Ground/ParallaxForeground" index="0"]

View File

@ -1018,10 +1018,13 @@ autostart = false
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": &"胖子呼吸", "animation_intro": &"胖子呼吸",
&"animation_next": "胖子走路", &"animation_next": "胖子走路",
"animation_wait_time": 0.0,
&"intro_loop": 6 &"intro_loop": 6
}]) }])
move_configs = Array[Dictionary]([{ move_configs = Array[Dictionary]([{
"animation": "胖子走路", "animation": "胖子走路",
"animation_next": "",
"duration": 1e+07,
"movement_x": 1000.0, "movement_x": 1000.0,
"velocity": Vector2(-65, 0) "velocity": Vector2(-65, 0)
}]) }])
@ -1043,10 +1046,13 @@ animation = &"小婵捂脸"
autostart = false autostart = false
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": "小婵捂脸", "animation_intro": "小婵捂脸",
&"animation_next": "小婵呼吸" &"animation_next": "小婵呼吸",
"animation_wait_time": 0.0,
"intro_loop": 1
}, { }, {
"animation_intro": &"小婵呼吸", "animation_intro": &"小婵呼吸",
&"animation_next": "小婵走路", &"animation_next": "小婵走路",
"animation_wait_time": 0.0,
&"intro_loop": 8 &"intro_loop": 8
}]) }])
move_configs = Array[Dictionary]([{ move_configs = Array[Dictionary]([{
@ -1068,10 +1074,13 @@ autostart = false
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": &"方瞎子呼吸-右", "animation_intro": &"方瞎子呼吸-右",
&"animation_next": "方瞎子走路-左", &"animation_next": "方瞎子走路-左",
"animation_wait_time": 0.0,
&"intro_loop": 7 &"intro_loop": 7
}]) }])
move_configs = Array[Dictionary]([{ move_configs = Array[Dictionary]([{
"animation": "方瞎子走路-左", "animation": "方瞎子走路-左",
"animation_next": "",
"duration": 1e+07,
"movement_x": 1000.0, "movement_x": 1000.0,
"velocity": Vector2(-50, 0) "velocity": Vector2(-50, 0)
}]) }])

View File

@ -19,7 +19,6 @@
[node name="Ground" parent="." instance=ExtResource("1_oao56")] [node name="Ground" parent="." instance=ExtResource("1_oao56")]
scene_name = "c02_s07" scene_name = "c02_s07"
player_y = 60 player_y = 60
main_scene = null
[node name="AnimationPlayer" parent="Ground" index="0"] [node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_t0s64") script = ExtResource("2_t0s64")
@ -94,7 +93,7 @@ position = Vector2(11, -1)
[node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"] [node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"]
points = PackedVector2Array(37, 150, 610, 150) points = PackedVector2Array(37, 150, 610, 150)
[node name="DirectionalLight2D" parent="Ground" index="8"] [node name="DirectionalLight2D" parent="Ground" index="7"]
visible = false visible = false
energy = 0.9 energy = 0.9
blend_mode = 1 blend_mode = 1

View File

@ -135,13 +135,12 @@ func _on_counter_interacted():
SceneManager.freeze_player(0) SceneManager.freeze_player(0)
var x = counter.global_position.x - player_pull_offset_x var x = counter.global_position.x - player_pull_offset_x
# 走到左侧 # 走到左侧
player.walk_to(Vector2(x, 98.0), 1.0) player.walk_to_x(x).tween_callback(func():
await get_tree().create_timer(1.1).timeout player.character = "吕萍推柜子"
SceneManager.release_player() player.lock_move_right = true
SceneManager.pop_center_notification(tr("ui_press_q_to_exit"))
)
player.position_updated.connect(on_player_moved_counter) player.position_updated.connect(on_player_moved_counter)
player.character = "吕萍推柜子"
player.lock_move_right = true
pushing_counter = !pushing_counter pushing_counter = !pushing_counter

View File

@ -238,7 +238,7 @@ position = Vector2(193, 0)
[node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"] [node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"]
points = PackedVector2Array(50, 150, 510, 150) points = PackedVector2Array(50, 150, 510, 150)
[node name="DirectionalLight2D" parent="Ground" index="8"] [node name="DirectionalLight2D" parent="Ground" index="7"]
visible = false visible = false
energy = 0.9 energy = 0.9
blend_mode = 1 blend_mode = 1

View File

@ -19,6 +19,7 @@ signal interacted
@onready var sfx_success = $SfxSuccess as Sfx @onready var sfx_success = $SfxSuccess as Sfx
@onready var sfx_bgm = $SfxBgm as AudioStreamPlayer @onready var sfx_bgm = $SfxBgm as AudioStreamPlayer
@onready var sign_mark = %Sign as Sign @onready var sign_mark = %Sign as Sign
@onready var sign_snapper = %SignSnapper as SignSnapper
@onready var area2d = %Area2D as Area2D @onready var area2d = %Area2D as Area2D
@onready var animated_sprite = $"小手" as AnimatedSprite2D @onready var animated_sprite = $"小手" as AnimatedSprite2D
@ -60,7 +61,8 @@ func _ready() -> void:
return return
area2d.body_entered.connect(_reset) area2d.body_entered.connect(_reset)
area2d.body_exited.connect(_on_exit) area2d.body_exited.connect(_on_exit)
sign_mark.interacted.connect(_on_interacted) # sign_mark.interacted.connect(_on_interacted)
sign_snapper.arrived.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel) sign_mark.cancel.connect(_on_cancel)
sign_mark.enabled = enabled sign_mark.enabled = enabled
@ -175,9 +177,6 @@ func _on_interacted() -> void:
# 对话 # 对话
if not communicating: if not communicating:
communicating = true communicating = true
# # 走到指定地点
# SceneManager.get_player().walk_to(Vector2(225, 98.0), 1.5)
# await SceneManager.get_player().animation_finished
animated_sprite.visible = false animated_sprite.visible = false
# 7 拿起纸杯 8 监听纸杯 # 7 拿起纸杯 8 监听纸杯
SceneManager.freeze_player(0, 7) SceneManager.freeze_player(0, 7)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=16 format=3 uid="uid://xovlfee503a4"] [gd_scene load_steps=17 format=3 uid="uid://xovlfee503a4"]
[ext_resource type="Texture2D" uid="uid://cawpq7rnho5px" path="res://asset/art/gif/c02_小手/洞.png" id="1_47cqy"] [ext_resource type="Texture2D" uid="uid://cawpq7rnho5px" path="res://asset/art/gif/c02_小手/洞.png" id="1_47cqy"]
[ext_resource type="Script" uid="uid://my5xqi3bkka6" path="res://scene/ground/script/c02/小手讨东西.gd" id="1_n7thl"] [ext_resource type="Script" uid="uid://my5xqi3bkka6" path="res://scene/ground/script/c02/小手讨东西.gd" id="1_n7thl"]
@ -14,6 +14,7 @@
[ext_resource type="SpriteFrames" uid="uid://b6nvwset1hwbv" path="res://asset/art/gif/c02_小手/c02_小手_frames.tres" id="9_yatcw"] [ext_resource type="SpriteFrames" uid="uid://b6nvwset1hwbv" path="res://asset/art/gif/c02_小手/c02_小手_frames.tres" id="9_yatcw"]
[ext_resource type="Texture2D" uid="uid://2mjipesnigcr" path="res://asset/art/prop/c02/锡箔元宝.png" id="10_47cqy"] [ext_resource type="Texture2D" uid="uid://2mjipesnigcr" path="res://asset/art/prop/c02/锡箔元宝.png" id="10_47cqy"]
[ext_resource type="PackedScene" uid="uid://dsa6frlw6e6gg" path="res://scene/entity/pickable.tscn" id="12_6lwlv"] [ext_resource type="PackedScene" uid="uid://dsa6frlw6e6gg" path="res://scene/entity/pickable.tscn" id="12_6lwlv"]
[ext_resource type="Script" uid="uid://cnt01hiw52bmn" path="res://scene/entity/ux/sign_snapper.gd" id="15_lr23o"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_yatcw"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_yatcw"]
resource_local_to_scene = true resource_local_to_scene = true
@ -115,3 +116,8 @@ show_behind_parent = true
position = Vector2(0, -14) position = Vector2(0, -14)
scale = Vector2(0.15, 0.15) scale = Vector2(0.15, 0.15)
texture = ExtResource("10_47cqy") texture = ExtResource("10_47cqy")
[node name="SignSnapper" type="Marker2D" parent="."]
unique_name_in_owner = true
script = ExtResource("15_lr23o")
metadata/_custom_type_script = "uid://cnt01hiw52bmn"

View File

@ -474,26 +474,35 @@ func set_y_from_ground(player_y: float) -> void:
global_position.y = player_y global_position.y = player_y
func walk_to(pos: Vector2, duration: float) -> void: func walk_to_x(global_pos_x: float, release_on_arrived := true) -> Tween:
return walk_to(Vector2(global_pos_x, global_position.y), release_on_arrived)
func walk_to(global_pos: Vector2, release_on_arrived := true) -> Tween:
var tween = create_tween() var tween = create_tween()
velocity = Vector2.ZERO velocity = Vector2.ZERO
if pos.x < global_position.x:
facing_direction.x = -1.0
elif pos.x > global_position.x:
facing_direction.x = 1.0
_check_status(facing_direction)
_play_animation()
if GlobalConfig.DEBUG: if GlobalConfig.DEBUG:
print("walk_to:", pos, duration, " from:", global_position) print("walk_to:", global_pos, " from:", global_position)
# 不同距离下,行走时长略做自适应 # 不同距离下,行走时长略做自适应
var time_cost = min(duration, global_position.distance_to(pos) / 50.0) var time_cost = absf(global_pos.distance_to(global_position) / 50.0)
if time_cost < duration: if time_cost > 0:
tween.tween_interval(duration - time_cost) freeze_player(0, 3, false)
tween.tween_property(self, "global_position", pos, time_cost) if global_pos.x < global_position.x:
tween.tween_callback(_after_walk_to) facing_direction.x = -1.0
elif global_pos.x > global_position.x:
facing_direction.x = 1.0
_check_status(facing_direction)
_play_animation()
tween.tween_property(self, "global_position", global_pos, time_cost)
tween.tween_callback(_after_walk_to.bind(release_on_arrived))
return tween
func _after_walk_to(): func _after_walk_to(release_on_arrived: bool) -> void:
velocity = Vector2.ZERO velocity = Vector2.ZERO
current_status = PlayerAnimationConfig.MOVEMENT_IDLE current_status = PlayerAnimationConfig.MOVEMENT_IDLE
_play_animation() _play_animation()
if release_on_arrived:
release_player()

View File

@ -76,3 +76,11 @@ func _unhandled_input(event: InputEvent) -> void:
AudioManager.play_sfx(close_stream) AudioManager.play_sfx(close_stream)
SceneManager.toggle_pause_counter(false) SceneManager.toggle_pause_counter(false)
queue_free() queue_free()
elif event.is_action_pressed("gallery"):
SceneManager.show_gallery()
SceneManager.toggle_pause_counter(false)
queue_free()

View File

@ -19,14 +19,22 @@ signal current_item_changed(prop_key: String)
@export var unviewed_important_items := [] @export var unviewed_important_items := []
@export var default_enabled_items := [] @export var default_enabled_items := []
@export var xdie_enabled_items := []
@export var xxdie_enabled_items := [] @export var xxdie_enabled_items := []
@export var xxxdie_enabled_items := [] @export var xxxdie_enabled_items := []
var enabled_items := [] var enabled_items := []
func checkout(character: String): func checkout(character: String):
# @export_enum("吕萍", "吕萍爬行", "吕萍带小猫", "吕萍推柜子", "小小蝶", "盒子猫", "小小小蝶") var character := "吕萍": # @export_enum("吕萍", "吕萍爬行", "吕萍带小猫", "吕萍推柜子", "小小蝶", "盒子猫", "小小小蝶") var character := "吕萍":
pass if character == "小小蝶":
enabled_items = xxdie_enabled_items
elif character == "小小小蝶":
enabled_items = xxxdie_enabled_items
elif character.substr(0, 2) == "吕萍":
enabled_items = xdie_enabled_items
else:
enabled_items = default_enabled_items
func enable_important_item(prop_key: String) -> void: func enable_important_item(prop_key: String) -> void:
@ -49,6 +57,7 @@ func enable_item(prop_key: String) -> void:
# 重复 enable 无负面影响 # 重复 enable 无负面影响
if not enabled_items.has(prop_key): if not enabled_items.has(prop_key):
enabled_items.append(prop_key) enabled_items.append(prop_key)
# 新增后直接选中 # 新增后直接选中
current_index = enabled_items.find(prop_key) current_index = enabled_items.find(prop_key)