设置与起始页面;书房使用鸡毛掸子动画;存档适配

This commit is contained in:
cakipaul 2025-01-16 20:24:21 +08:00
parent f044829520
commit 1e58baf371
110 changed files with 1654 additions and 303 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -16,6 +16,22 @@ c02_获得火柴,火柴,,获得,,[#item]
c02_1014钥匙,1014钥匙,,获得,,[#item] c02_1014钥匙,1014钥匙,,获得,,[#item]
c02_老鼠洞1,一个老鼠洞,,,, c02_老鼠洞1,一个老鼠洞,,,,
c02_老鼠洞2,在这种楼里挺常见的,,,, c02_老鼠洞2,在这种楼里挺常见的,,,,
ui_新游戏,新游戏,,,,
ui_继续游戏,继续游戏,,,,
ui_退出游戏,退出游戏,,,,
index_新游戏,新游戏,,,,
index_继续游戏,继续游戏,,,,
index_退出游戏,退出游戏,,,,
setting_总音量,总音量,,,,
setting_音效音量,音效音量,,,,
setting_对话音量,对话音量,,,,
setting_全屏游戏,全屏游戏,,,,
setting_窗口置顶,窗口置顶,,,,
setting_自动保存,自动保存,,,,
setting_主界面,回到主界面,,,,
setting_退出,保存并退出,,,,
setting_日志,打开日志,,,,
ui_秒,秒,,,,
ui_获得,获得,,,, ui_获得,获得,,,,
ui_退出,退出,Exit,,, ui_退出,退出,Exit,,,
ui_阅读,阅读,Read,,, ui_阅读,阅读,Read,,,

1 keys zh_CN en _character _notes _tags
16 c02_1014钥匙 1014钥匙 获得 [#item]
17 c02_老鼠洞1 一个老鼠洞
18 c02_老鼠洞2 在这种楼里挺常见的
19 ui_新游戏 新游戏
20 ui_继续游戏 继续游戏
21 ui_退出游戏 退出游戏
22 index_新游戏 新游戏
23 index_继续游戏 继续游戏
24 index_退出游戏 退出游戏
25 setting_总音量 总音量
26 setting_音效音量 音效音量
27 setting_对话音量 对话音量
28 setting_全屏游戏 全屏游戏
29 setting_窗口置顶 窗口置顶
30 setting_自动保存 自动保存
31 setting_主界面 回到主界面
32 setting_退出 保存并退出
33 setting_日志 打开日志
34 ui_秒
35 ui_获得 获得
36 ui_退出 退出 Exit
37 ui_阅读 阅读 Read

View File

@ -1,9 +1,26 @@
# UI # UI
~ UI ~ UI
新游戏[ID:index_新游戏]
继续游戏[ID:index_继续游戏]
退出游戏[ID:index_退出游戏]
总音量[ID:setting_总音量]
音效音量[ID:setting_音效音量]
对话音量[ID:setting_对话音量]
全屏游戏[ID:setting_全屏游戏]
窗口置顶[ID:setting_窗口置顶]
自动保存[ID:setting_自动保存]
回到主界面[ID:setting_主界面]
保存并退出[ID:setting_退出]
打开日志[ID:setting_日志]
秒 [ID:ui_秒]
获得 [ID:ui_获得] 获得 [ID:ui_获得]
退出 [ID:ui_退出] 退出 [ID:ui_退出]
阅读 [ID:ui_阅读] 阅读 [ID:ui_阅读]
收起 [ID:ui_收起] 收起 [ID:ui_收起]
=> END => END
~ PropItems ~ PropItems

View File

@ -1,4 +1,4 @@
[gd_resource type="SpriteFrames" load_steps=483 format=3 uid="uid://b7fhheih1hbvf"] [gd_resource type="SpriteFrames" load_steps=525 format=3 uid="uid://b7fhheih1hbvf"]
[ext_resource type="Texture2D" uid="uid://b302alg8wwgs1" path="res://asset/art/animation/c00_吕萍_记笔记_right/吕萍-拿本子记录1.png" id="1_6sdvl"] [ext_resource type="Texture2D" uid="uid://b302alg8wwgs1" path="res://asset/art/animation/c00_吕萍_记笔记_right/吕萍-拿本子记录1.png" id="1_6sdvl"]
[ext_resource type="Texture2D" uid="uid://d1kvhxsx8c4dv" path="res://asset/art/animation/c00_吕萍_idle_left/zhhx1.png" id="1_ekv0l"] [ext_resource type="Texture2D" uid="uid://d1kvhxsx8c4dv" path="res://asset/art/animation/c00_吕萍_idle_left/zhhx1.png" id="1_ekv0l"]
@ -177,20 +177,20 @@
[ext_resource type="Texture2D" uid="uid://dbr1e3oj6mn18" path="res://asset/art/animation/c01_小小蝶_running/7.png" id="112_m4xei"] [ext_resource type="Texture2D" uid="uid://dbr1e3oj6mn18" path="res://asset/art/animation/c01_小小蝶_running/7.png" id="112_m4xei"]
[ext_resource type="Texture2D" uid="uid://cm4jq06hnfjky" path="res://asset/art/animation/c01_小小蝶_running_l/4.png" id="112_q7dxw"] [ext_resource type="Texture2D" uid="uid://cm4jq06hnfjky" path="res://asset/art/animation/c01_小小蝶_running_l/4.png" id="112_q7dxw"]
[ext_resource type="Texture2D" uid="uid://c11wut0wqfdi" path="res://asset/art/animation/c01_捡球男孩_关键帧/58.png" id="112_r2dja"] [ext_resource type="Texture2D" uid="uid://c11wut0wqfdi" path="res://asset/art/animation/c01_捡球男孩_关键帧/58.png" id="112_r2dja"]
[ext_resource type="Texture2D" uid="uid://b6pnpwc5yayll" path="res://asset/art/animation/c01_小小蝶_walking/1.png" id="113_1lrkx"] [ext_resource type="Texture2D" uid="uid://cf33fydn77q8e" path="res://asset/art/animation/c01_小小蝶_walking/1.png" id="113_1lrkx"]
[ext_resource type="Texture2D" uid="uid://oov8gpedrahp" path="res://asset/art/animation/c01_小小蝶_running_l/5.png" id="113_36gw6"] [ext_resource type="Texture2D" uid="uid://oov8gpedrahp" path="res://asset/art/animation/c01_小小蝶_running_l/5.png" id="113_36gw6"]
[ext_resource type="Texture2D" uid="uid://wxug6ssoqsek" path="res://asset/art/animation/c01_捡球男孩_关键帧/59.png" id="113_a8pao"] [ext_resource type="Texture2D" uid="uid://wxug6ssoqsek" path="res://asset/art/animation/c01_捡球男孩_关键帧/59.png" id="113_a8pao"]
[ext_resource type="Texture2D" uid="uid://djdd3g0hfblbs" path="res://asset/art/animation/c01_捡球男孩_关键帧/60.png" id="114_2m6mm"] [ext_resource type="Texture2D" uid="uid://djdd3g0hfblbs" path="res://asset/art/animation/c01_捡球男孩_关键帧/60.png" id="114_2m6mm"]
[ext_resource type="Texture2D" uid="uid://dj32v1m8ssy0f" path="res://asset/art/animation/c01_小小蝶_running_l/6.png" id="114_7cu0w"] [ext_resource type="Texture2D" uid="uid://dj32v1m8ssy0f" path="res://asset/art/animation/c01_小小蝶_running_l/6.png" id="114_7cu0w"]
[ext_resource type="Texture2D" uid="uid://0el4ahvvd1wo" path="res://asset/art/animation/c01_小小蝶_walking/2.png" id="114_i8ndl"] [ext_resource type="Texture2D" uid="uid://bfg215qukp2ls" path="res://asset/art/animation/c01_小小蝶_walking/2.png" id="114_i8ndl"]
[ext_resource type="Texture2D" uid="uid://do2lfqkimxluq" path="res://asset/art/animation/c01_捡球男孩_关键帧/61.png" id="115_ct7bj"] [ext_resource type="Texture2D" uid="uid://do2lfqkimxluq" path="res://asset/art/animation/c01_捡球男孩_关键帧/61.png" id="115_ct7bj"]
[ext_resource type="Texture2D" uid="uid://c56ny2uvbvemy" path="res://asset/art/animation/c01_小小蝶_walking/3.png" id="115_gfdtf"] [ext_resource type="Texture2D" uid="uid://do1easroaepeq" path="res://asset/art/animation/c01_小小蝶_walking/3.png" id="115_gfdtf"]
[ext_resource type="Texture2D" uid="uid://ctbjx54sahbf7" path="res://asset/art/animation/c01_小小蝶_running_l/7.png" id="115_ink27"] [ext_resource type="Texture2D" uid="uid://ctbjx54sahbf7" path="res://asset/art/animation/c01_小小蝶_running_l/7.png" id="115_ink27"]
[ext_resource type="Texture2D" uid="uid://46j7vl8efysd" path="res://asset/art/animation/c01_红光鬼差_idle/1.png" id="116_4yqm5"] [ext_resource type="Texture2D" uid="uid://46j7vl8efysd" path="res://asset/art/animation/c01_红光鬼差_idle/1.png" id="116_4yqm5"]
[ext_resource type="Texture2D" uid="uid://bva4ih8hnolk6" path="res://asset/art/animation/c01_小小蝶_walking/4.png" id="116_ql6a7"] [ext_resource type="Texture2D" uid="uid://c6a85pmjf7vrt" path="res://asset/art/animation/c01_小小蝶_walking/4.png" id="116_ql6a7"]
[ext_resource type="Texture2D" uid="uid://tn65scbpfnne" path="res://asset/art/animation/c01_小小蝶_walking/5.png" id="117_1a4yh"] [ext_resource type="Texture2D" uid="uid://meluveunuj0m" path="res://asset/art/animation/c01_小小蝶_walking/5.png" id="117_1a4yh"]
[ext_resource type="Texture2D" uid="uid://cpix43k76ietl" path="res://asset/art/animation/c01_红光鬼差_idle/2.png" id="117_sve2i"] [ext_resource type="Texture2D" uid="uid://cpix43k76ietl" path="res://asset/art/animation/c01_红光鬼差_idle/2.png" id="117_sve2i"]
[ext_resource type="Texture2D" uid="uid://cyamtfo255jkp" path="res://asset/art/animation/c01_小小蝶_walking/6.png" id="118_2n8cs"] [ext_resource type="Texture2D" uid="uid://clwimhs8w4bsl" path="res://asset/art/animation/c01_小小蝶_walking/6.png" id="118_2n8cs"]
[ext_resource type="Texture2D" uid="uid://bs00u1clx2ayt" path="res://asset/art/animation/c01_红光鬼差_idle/3.png" id="118_3t3jm"] [ext_resource type="Texture2D" uid="uid://bs00u1clx2ayt" path="res://asset/art/animation/c01_红光鬼差_idle/3.png" id="118_3t3jm"]
[ext_resource type="Texture2D" uid="uid://dwyaoo37xqfex" path="res://asset/art/animation/c01_红光鬼差_idle/4.png" id="119_c788p"] [ext_resource type="Texture2D" uid="uid://dwyaoo37xqfex" path="res://asset/art/animation/c01_红光鬼差_idle/4.png" id="119_c788p"]
[ext_resource type="Texture2D" uid="uid://c7wo7x1wewwqe" path="res://asset/art/animation/c01_小小蝶_抬头/1.png" id="119_gj714"] [ext_resource type="Texture2D" uid="uid://c7wo7x1wewwqe" path="res://asset/art/animation/c01_小小蝶_抬头/1.png" id="119_gj714"]
@ -200,56 +200,86 @@
[ext_resource type="Texture2D" uid="uid://c4x43qlufshfa" path="res://asset/art/animation/c01_小小蝶_抬头/3.png" id="121_y4tby"] [ext_resource type="Texture2D" uid="uid://c4x43qlufshfa" path="res://asset/art/animation/c01_小小蝶_抬头/3.png" id="121_y4tby"]
[ext_resource type="Texture2D" uid="uid://cphrmak1vavv7" path="res://asset/art/animation/c01_红光鬼差_walking/3.png" id="122_rmksf"] [ext_resource type="Texture2D" uid="uid://cphrmak1vavv7" path="res://asset/art/animation/c01_红光鬼差_walking/3.png" id="122_rmksf"]
[ext_resource type="Texture2D" uid="uid://ctbdcj18n4lod" path="res://asset/art/animation/c01_小小蝶_抬头/4.png" id="122_wi84v"] [ext_resource type="Texture2D" uid="uid://ctbdcj18n4lod" path="res://asset/art/animation/c01_小小蝶_抬头/4.png" id="122_wi84v"]
[ext_resource type="Texture2D" uid="uid://bnigayx6uu3c6" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/1.png" id="123_1rifq"]
[ext_resource type="Texture2D" uid="uid://cfsbtgvo7peet" path="res://asset/art/animation/c01_红光鬼差_walking/4.png" id="123_4v81v"] [ext_resource type="Texture2D" uid="uid://cfsbtgvo7peet" path="res://asset/art/animation/c01_红光鬼差_walking/4.png" id="123_4v81v"]
[ext_resource type="Texture2D" uid="uid://1ov6qyaua0bx" path="res://asset/art/animation/c01_小小蝶_抬头/5.png" id="123_aidva"] [ext_resource type="Texture2D" uid="uid://1ov6qyaua0bx" path="res://asset/art/animation/c01_小小蝶_抬头/5.png" id="123_aidva"]
[ext_resource type="Texture2D" uid="uid://bwwbhba6s555j" path="res://asset/art/animation/c01_小小蝶_walking_l/1.png" id="123_ip1br"]
[ext_resource type="Texture2D" uid="uid://b3ag537dmcfu" path="res://asset/art/animation/c01_车夫_idle/1.png" id="124_ddngu"] [ext_resource type="Texture2D" uid="uid://b3ag537dmcfu" path="res://asset/art/animation/c01_车夫_idle/1.png" id="124_ddngu"]
[ext_resource type="Texture2D" uid="uid://uy3b1st1hlqi" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/2.png" id="124_f05ht"]
[ext_resource type="Texture2D" uid="uid://caisrlme7liwx" path="res://asset/art/animation/c01_小小蝶_抬头/6.png" id="124_ndtdx"] [ext_resource type="Texture2D" uid="uid://caisrlme7liwx" path="res://asset/art/animation/c01_小小蝶_抬头/6.png" id="124_ndtdx"]
[ext_resource type="Texture2D" uid="uid://ca4msckhhv5hy" path="res://asset/art/animation/c01_小小蝶_walking_l/2.png" id="124_ufqlo"]
[ext_resource type="Texture2D" uid="uid://c8ctetgosxik" path="res://asset/art/animation/c01_车夫_idle/2.png" id="125_6fqgx"] [ext_resource type="Texture2D" uid="uid://c8ctetgosxik" path="res://asset/art/animation/c01_车夫_idle/2.png" id="125_6fqgx"]
[ext_resource type="Texture2D" uid="uid://bgv3d00iclj1f" path="res://asset/art/animation/c01_小小蝶_walking_l/3.png" id="125_ftpsa"] [ext_resource type="Texture2D" uid="uid://bn572lpa8kvkn" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/3.png" id="125_bxjt8"]
[ext_resource type="Texture2D" uid="uid://blljbvkam6vqu" path="res://asset/art/animation/c01_小小蝶_抬头/7.png" id="125_hl2pe"] [ext_resource type="Texture2D" uid="uid://blljbvkam6vqu" path="res://asset/art/animation/c01_小小蝶_抬头/7.png" id="125_hl2pe"]
[ext_resource type="Texture2D" uid="uid://dsm5npxmjwt7" path="res://asset/art/animation/c01_车夫_idle/3.png" id="126_5j17f"] [ext_resource type="Texture2D" uid="uid://dsm5npxmjwt7" path="res://asset/art/animation/c01_车夫_idle/3.png" id="126_5j17f"]
[ext_resource type="Texture2D" uid="uid://6nxt1l5sngsi" path="res://asset/art/animation/c01_小小蝶_walking_l/4.png" id="126_q6eiw"] [ext_resource type="Texture2D" uid="uid://bridfp7wni8j8" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/4.png" id="126_yy7k4"]
[ext_resource type="Texture2D" uid="uid://bsh1g7gus1xkh" path="res://asset/art/animation/c01_车夫_running/1.png" id="127_8yqif"] [ext_resource type="Texture2D" uid="uid://bsh1g7gus1xkh" path="res://asset/art/animation/c01_车夫_running/1.png" id="127_8yqif"]
[ext_resource type="Texture2D" uid="uid://bkuui6ud0jhje" path="res://asset/art/animation/c01_小小蝶_walking_l/5.png" id="127_fucof"] [ext_resource type="Texture2D" uid="uid://qwj84jjgqafp" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/5.png" id="127_riraf"]
[ext_resource type="Texture2D" uid="uid://dwwvebtr7yv2i" path="res://asset/art/animation/c01_小小蝶_walking_l/6.png" id="128_6ydk7"] [ext_resource type="Texture2D" uid="uid://dywnuaj88cqkt" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/6.png" id="128_r5txh"]
[ext_resource type="Texture2D" uid="uid://bp4fqgaybkrmq" path="res://asset/art/animation/c01_车夫_running/2.png" id="128_vv2bn"] [ext_resource type="Texture2D" uid="uid://bp4fqgaybkrmq" path="res://asset/art/animation/c01_车夫_running/2.png" id="128_vv2bn"]
[ext_resource type="Texture2D" uid="uid://dj4gp8bp4i1ty" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/7.png" id="129_8qeg7"]
[ext_resource type="Texture2D" uid="uid://dgvk7pv7o7stj" path="res://asset/art/animation/c01_车夫_running/3.png" id="129_caif4"] [ext_resource type="Texture2D" uid="uid://dgvk7pv7o7stj" path="res://asset/art/animation/c01_车夫_running/3.png" id="129_caif4"]
[ext_resource type="Texture2D" uid="uid://ywprdxq8508f" path="res://asset/art/animation/c01_小小蝶_walking 8帧-317px高/8.png" id="130_lpb6w"]
[ext_resource type="Texture2D" uid="uid://cc2fns0l7u3pp" path="res://asset/art/animation/c01_车夫_running/4.png" id="130_th40a"] [ext_resource type="Texture2D" uid="uid://cc2fns0l7u3pp" path="res://asset/art/animation/c01_车夫_running/4.png" id="130_th40a"]
[ext_resource type="Texture2D" uid="uid://bug2xlj0qk37t" path="res://asset/art/animation/c01_车夫_running/5.png" id="131_g1eop"] [ext_resource type="Texture2D" uid="uid://bug2xlj0qk37t" path="res://asset/art/animation/c01_车夫_running/5.png" id="131_g1eop"]
[ext_resource type="Texture2D" uid="uid://blebfaaign0n2" path="res://asset/art/animation/c01_小小蝶_walking_l/1.png" id="131_w281a"]
[ext_resource type="Texture2D" uid="uid://f32plo5jnpmv" path="res://asset/art/animation/c01_车夫_running/6.png" id="132_08jtn"] [ext_resource type="Texture2D" uid="uid://f32plo5jnpmv" path="res://asset/art/animation/c01_车夫_running/6.png" id="132_08jtn"]
[ext_resource type="Texture2D" uid="uid://ds7xrq7d10mnj" path="res://asset/art/animation/c01_小小蝶_walking_l/2.png" id="132_eeag4"]
[ext_resource type="Texture2D" uid="uid://cptyploojapl4" path="res://asset/art/animation/c01_车夫_running/7.png" id="133_4swv0"] [ext_resource type="Texture2D" uid="uid://cptyploojapl4" path="res://asset/art/animation/c01_车夫_running/7.png" id="133_4swv0"]
[ext_resource type="Texture2D" uid="uid://dt4lpgh6lb1ht" path="res://asset/art/animation/c01_小小蝶_walking_l/3.png" id="133_fpldy"]
[ext_resource type="Texture2D" uid="uid://dnqiwerwu6hk" path="res://asset/art/animation/c01_车夫_running/8.png" id="134_ti84l"] [ext_resource type="Texture2D" uid="uid://dnqiwerwu6hk" path="res://asset/art/animation/c01_车夫_running/8.png" id="134_ti84l"]
[ext_resource type="Texture2D" uid="uid://du1c6b5aks6lw" path="res://asset/art/animation/c01_小小蝶_walking_l/4.png" id="134_x6ki2"]
[ext_resource type="Texture2D" uid="uid://dl22yamvk6sni" path="res://asset/art/animation/c01_小小蝶_walking_l/5.png" id="135_5fneh"]
[ext_resource type="Texture2D" uid="uid://dn2uxlvnv34il" path="res://asset/art/animation/c01_小小蝶_抬头_l/1.png" id="135_h2mh7"] [ext_resource type="Texture2D" uid="uid://dn2uxlvnv34il" path="res://asset/art/animation/c01_小小蝶_抬头_l/1.png" id="135_h2mh7"]
[ext_resource type="Texture2D" uid="uid://56kx8a82ib52" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/1.png" id="135_hth06"]
[ext_resource type="Texture2D" uid="uid://bqkd5gpatio6m" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/1.png" id="135_s0r05"] [ext_resource type="Texture2D" uid="uid://bqkd5gpatio6m" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/1.png" id="135_s0r05"]
[ext_resource type="Texture2D" uid="uid://cektc618xlff7" path="res://asset/art/animation/c01_小小蝶_抬头_l/2.png" id="136_g5ypq"] [ext_resource type="Texture2D" uid="uid://cektc618xlff7" path="res://asset/art/animation/c01_小小蝶_抬头_l/2.png" id="136_g5ypq"]
[ext_resource type="Texture2D" uid="uid://bomocj4mxny1g" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/2.png" id="136_ko460"]
[ext_resource type="Texture2D" uid="uid://b78kg5eoynobw" path="res://asset/art/animation/c01_小小蝶_walking_l/6.png" id="136_rej31"]
[ext_resource type="Texture2D" uid="uid://k7hihwxiqbp3" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/2.png" id="136_vxrfs"] [ext_resource type="Texture2D" uid="uid://k7hihwxiqbp3" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/2.png" id="136_vxrfs"]
[ext_resource type="Texture2D" uid="uid://bt1hyxi10vcqg" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/3.png" id="137_1k3xv"]
[ext_resource type="Texture2D" uid="uid://n62ks0pmmjm8" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/3.png" id="137_gpg4r"] [ext_resource type="Texture2D" uid="uid://n62ks0pmmjm8" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/3.png" id="137_gpg4r"]
[ext_resource type="Texture2D" uid="uid://opacanxf15l2" path="res://asset/art/animation/c01_小小蝶_抬头_l/3.png" id="137_mm3py"] [ext_resource type="Texture2D" uid="uid://opacanxf15l2" path="res://asset/art/animation/c01_小小蝶_抬头_l/3.png" id="137_mm3py"]
[ext_resource type="Texture2D" uid="uid://c7d5feogf0x31" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/4.png" id="138_3e8uw"] [ext_resource type="Texture2D" uid="uid://c7d5feogf0x31" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/4.png" id="138_3e8uw"]
[ext_resource type="Texture2D" uid="uid://dmutunm61btih" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/4.png" id="138_s23im"]
[ext_resource type="Texture2D" uid="uid://c3icsu2c6c60w" path="res://asset/art/animation/c01_小小蝶_抬头_l/4.png" id="138_uoqgs"] [ext_resource type="Texture2D" uid="uid://c3icsu2c6c60w" path="res://asset/art/animation/c01_小小蝶_抬头_l/4.png" id="138_uoqgs"]
[ext_resource type="Texture2D" uid="uid://qp7qxg7uuvdf" path="res://asset/art/animation/c01_小小蝶_抬头_l/5.png" id="139_01v8j"] [ext_resource type="Texture2D" uid="uid://qp7qxg7uuvdf" path="res://asset/art/animation/c01_小小蝶_抬头_l/5.png" id="139_01v8j"]
[ext_resource type="Texture2D" uid="uid://c8tbq4mhafyt6" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/5.png" id="139_odkro"] [ext_resource type="Texture2D" uid="uid://c8tbq4mhafyt6" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/5.png" id="139_odkro"]
[ext_resource type="Texture2D" uid="uid://j1nwd7ut8cql" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/5.png" id="139_xn4xi"]
[ext_resource type="Texture2D" uid="uid://cy4fcdbjashvq" path="res://asset/art/animation/c01_小小蝶_抬头_l/6.png" id="140_47ycv"] [ext_resource type="Texture2D" uid="uid://cy4fcdbjashvq" path="res://asset/art/animation/c01_小小蝶_抬头_l/6.png" id="140_47ycv"]
[ext_resource type="Texture2D" uid="uid://c7eiqc73dcyu1" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/6.png" id="140_mneg6"] [ext_resource type="Texture2D" uid="uid://c7eiqc73dcyu1" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/6.png" id="140_mneg6"]
[ext_resource type="Texture2D" uid="uid://dlnr2elib7jku" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/6.png" id="140_sr1sq"]
[ext_resource type="Texture2D" uid="uid://csmhi2ee1o061" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/7.png" id="141_7m3gv"] [ext_resource type="Texture2D" uid="uid://csmhi2ee1o061" path="res://asset/art/animation/c02_吕萍_匍匐起身蹲着窥视/7.png" id="141_7m3gv"]
[ext_resource type="Texture2D" uid="uid://dk6scbhy4y0m7" path="res://asset/art/animation/c01_小小蝶_抬头_l/7.png" id="141_75qdx"] [ext_resource type="Texture2D" uid="uid://dk6scbhy4y0m7" path="res://asset/art/animation/c01_小小蝶_抬头_l/7.png" id="141_75qdx"]
[ext_resource type="Texture2D" uid="uid://doaam8u28r64s" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/7.png" id="141_sutp8"]
[ext_resource type="Texture2D" uid="uid://db21nmho8lhc3" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/8.png" id="142_ituys"]
[ext_resource type="Texture2D" uid="uid://chucfhljgvevj" path="res://asset/art/animation/c02_吕萍_坐着站起来/1.png" id="142_k1xsb"] [ext_resource type="Texture2D" uid="uid://chucfhljgvevj" path="res://asset/art/animation/c02_吕萍_坐着站起来/1.png" id="142_k1xsb"]
[ext_resource type="Texture2D" uid="uid://bxsj8enva4365" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/9.png" id="143_2aqu1"]
[ext_resource type="Texture2D" uid="uid://ddeidq5w3edbr" path="res://asset/art/animation/c02_吕萍_坐着站起来/2.png" id="143_5l1dh"] [ext_resource type="Texture2D" uid="uid://ddeidq5w3edbr" path="res://asset/art/animation/c02_吕萍_坐着站起来/2.png" id="143_5l1dh"]
[ext_resource type="Texture2D" uid="uid://kil0ej4xvj2l" path="res://asset/art/animation/c02_吕萍_坐着站起来/3.png" id="144_hoxm5"] [ext_resource type="Texture2D" uid="uid://kil0ej4xvj2l" path="res://asset/art/animation/c02_吕萍_坐着站起来/3.png" id="144_hoxm5"]
[ext_resource type="Texture2D" uid="uid://k85yu17tr1xs" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/10.png" id="144_m77af"]
[ext_resource type="Texture2D" uid="uid://bw7vgcch5u4xu" path="res://asset/art/animation/c01_小小蝶_侧面下蹲/11.png" id="145_3wuv4"]
[ext_resource type="Texture2D" uid="uid://d36l21jirpfl8" path="res://asset/art/animation/c02_吕萍_坐着站起来/4.png" id="145_l5pov"] [ext_resource type="Texture2D" uid="uid://d36l21jirpfl8" path="res://asset/art/animation/c02_吕萍_坐着站起来/4.png" id="145_l5pov"]
[ext_resource type="Texture2D" uid="uid://c6o6exw71g50o" path="res://asset/art/animation/c02_吕萍_坐着站起来/5.png" id="146_80x36"] [ext_resource type="Texture2D" uid="uid://c6o6exw71g50o" path="res://asset/art/animation/c02_吕萍_坐着站起来/5.png" id="146_80x36"]
[ext_resource type="Texture2D" uid="uid://dtaxqeof0maph" path="res://asset/art/animation/c01_小小蝶_床上看书/1.png" id="146_glua7"]
[ext_resource type="Texture2D" uid="uid://dnx1hemauii1l" path="res://asset/art/animation/c02_吕萍_坐着站起来/6.png" id="147_5dg5p"] [ext_resource type="Texture2D" uid="uid://dnx1hemauii1l" path="res://asset/art/animation/c02_吕萍_坐着站起来/6.png" id="147_5dg5p"]
[ext_resource type="Texture2D" uid="uid://b74jnipvkbwmd" path="res://asset/art/animation/c01_小小蝶_床上看书/2.png" id="147_jn0hd"]
[ext_resource type="Texture2D" uid="uid://c7sq73g6yjb2o" path="res://asset/art/animation/c01_小小蝶_床上看书/3.png" id="148_gtwc1"]
[ext_resource type="Texture2D" uid="uid://du1vt3xr4vk4s" path="res://asset/art/animation/c02_吕萍_坐着站起来/7.png" id="148_ii2r7"] [ext_resource type="Texture2D" uid="uid://du1vt3xr4vk4s" path="res://asset/art/animation/c02_吕萍_坐着站起来/7.png" id="148_ii2r7"]
[ext_resource type="Texture2D" uid="uid://b5u16fkkigq4e" path="res://asset/art/animation/c01_小小蝶_床上看书/4.png" id="149_ahx2r"]
[ext_resource type="Texture2D" uid="uid://blpnghe7wvn3w" path="res://asset/art/animation/c02_吕萍_坐着站起来/8.png" id="149_dvcto"] [ext_resource type="Texture2D" uid="uid://blpnghe7wvn3w" path="res://asset/art/animation/c02_吕萍_坐着站起来/8.png" id="149_dvcto"]
[ext_resource type="Texture2D" uid="uid://dutlv1uv81kvr" path="res://asset/art/animation/c01_小小蝶_床上看书/5.png" id="150_e3kfb"]
[ext_resource type="Texture2D" uid="uid://bvp5bcpkwbt50" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下1.png" id="150_eux3r"] [ext_resource type="Texture2D" uid="uid://bvp5bcpkwbt50" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下1.png" id="150_eux3r"]
[ext_resource type="Texture2D" uid="uid://mxjs6pjr715v" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下2.png" id="151_jlkuh"] [ext_resource type="Texture2D" uid="uid://mxjs6pjr715v" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下2.png" id="151_jlkuh"]
[ext_resource type="Texture2D" uid="uid://kjhgxseg8rx" path="res://asset/art/animation/c01_小小蝶_床上看书/6.png" id="151_p6hft"]
[ext_resource type="Texture2D" uid="uid://djcua53nt3r42" path="res://asset/art/animation/c01_小小蝶_床上看书/7.png" id="152_aeo40"]
[ext_resource type="Texture2D" uid="uid://coxghigohreuk" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下3.png" id="152_ogjo3"] [ext_resource type="Texture2D" uid="uid://coxghigohreuk" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下3.png" id="152_ogjo3"]
[ext_resource type="Texture2D" uid="uid://boipfvsictg5q" path="res://asset/art/animation/c01_小小蝶_床上看书/8.png" id="153_a380e"]
[ext_resource type="Texture2D" uid="uid://bh06l3ei6vfff" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下4.png" id="153_kgu3s"] [ext_resource type="Texture2D" uid="uid://bh06l3ei6vfff" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下4.png" id="153_kgu3s"]
[ext_resource type="Texture2D" uid="uid://0yqkigx8n405" path="res://asset/art/animation/c01_小小蝶_床上看书/9.png" id="154_3io2u"]
[ext_resource type="Texture2D" uid="uid://blf1htnwys1ua" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下5.png" id="154_p0rmp"] [ext_resource type="Texture2D" uid="uid://blf1htnwys1ua" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下5.png" id="154_p0rmp"]
[ext_resource type="Texture2D" uid="uid://dgthuc25ep881" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下6.png" id="155_8ksnh"] [ext_resource type="Texture2D" uid="uid://dgthuc25ep881" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下6.png" id="155_8ksnh"]
[ext_resource type="Texture2D" uid="uid://dayqvbkufaekq" path="res://asset/art/animation/c01_小小蝶_床上看书/10.png" id="155_rya2f"]
[ext_resource type="Texture2D" uid="uid://cbapyqasy2fj8" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下7.png" id="156_8l4v3"] [ext_resource type="Texture2D" uid="uid://cbapyqasy2fj8" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下7.png" id="156_8l4v3"]
[ext_resource type="Texture2D" uid="uid://cf5tr0dmc3es" path="res://asset/art/animation/c01_小小蝶_床上看书/11.png" id="156_nj42l"]
[ext_resource type="Texture2D" uid="uid://dldje87domhxw" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下8.png" id="157_krt3v"] [ext_resource type="Texture2D" uid="uid://dldje87domhxw" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下8.png" id="157_krt3v"]
[ext_resource type="Texture2D" uid="uid://cjq3xdh6rnshb" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下9.png" id="158_ere7d"] [ext_resource type="Texture2D" uid="uid://cjq3xdh6rnshb" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下9.png" id="158_ere7d"]
[ext_resource type="Texture2D" uid="uid://ca71jifap0omt" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下10.png" id="159_3yr4y"] [ext_resource type="Texture2D" uid="uid://ca71jifap0omt" path="res://asset/art/animation/c02_吕萍_头痛蹲下/吕萍-头痛蹲下10.png" id="159_3yr4y"]
@ -264,18 +294,30 @@
[ext_resource type="Texture2D" uid="uid://bp8r7ibvkrone" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/2.png" id="168_73fgv"] [ext_resource type="Texture2D" uid="uid://bp8r7ibvkrone" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/2.png" id="168_73fgv"]
[ext_resource type="Texture2D" uid="uid://bbuiblttnlt5b" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/3.png" id="169_jwrik"] [ext_resource type="Texture2D" uid="uid://bbuiblttnlt5b" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/3.png" id="169_jwrik"]
[ext_resource type="Texture2D" uid="uid://cg61vx4s103vs" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/4.png" id="170_2tgum"] [ext_resource type="Texture2D" uid="uid://cg61vx4s103vs" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/4.png" id="170_2tgum"]
[ext_resource type="Texture2D" uid="uid://bi4b5n4o1chwp" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/1.png" id="171_4j5x4"]
[ext_resource type="Texture2D" uid="uid://cj45qnehn02no" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/5.png" id="171_uhvv7"] [ext_resource type="Texture2D" uid="uid://cj45qnehn02no" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/5.png" id="171_uhvv7"]
[ext_resource type="Texture2D" uid="uid://vfpfj253ms55" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/2.png" id="172_f0811"]
[ext_resource type="Texture2D" uid="uid://b0ym3c7a2ugyj" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/6.png" id="172_u3c58"] [ext_resource type="Texture2D" uid="uid://b0ym3c7a2ugyj" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/6.png" id="172_u3c58"]
[ext_resource type="Texture2D" uid="uid://cfcix7sbdvbax" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/7.png" id="173_tileq"] [ext_resource type="Texture2D" uid="uid://cfcix7sbdvbax" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/7.png" id="173_tileq"]
[ext_resource type="Texture2D" uid="uid://5pp0h4qc4qhi" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/3.png" id="173_yiq1s"]
[ext_resource type="Texture2D" uid="uid://dcveqabcj5lgo" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/8.png" id="174_k2187"] [ext_resource type="Texture2D" uid="uid://dcveqabcj5lgo" path="res://asset/art/animation/c02_吕萍_柜前被吓到后退/8.png" id="174_k2187"]
[ext_resource type="Texture2D" uid="uid://cyv3rc3867ikc" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/4.png" id="174_qoowv"]
[ext_resource type="Texture2D" uid="uid://dww5hki3hiyu2" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/5.png" id="175_75miw"]
[ext_resource type="Texture2D" uid="uid://c7xb5h47dgide" path="res://asset/art/animation/c02_吕萍_爬出洞口/1.png" id="175_ikk0u"] [ext_resource type="Texture2D" uid="uid://c7xb5h47dgide" path="res://asset/art/animation/c02_吕萍_爬出洞口/1.png" id="175_ikk0u"]
[ext_resource type="Texture2D" uid="uid://ho07bn8n2gv5" path="res://asset/art/animation/c02_吕萍_爬出洞口/6.png" id="176_j4mr7"] [ext_resource type="Texture2D" uid="uid://ho07bn8n2gv5" path="res://asset/art/animation/c02_吕萍_爬出洞口/6.png" id="176_j4mr7"]
[ext_resource type="Texture2D" uid="uid://6ccao4s3ywyp" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/6.png" id="176_sre1c"]
[ext_resource type="Texture2D" uid="uid://c07fs4qbytxl5" path="res://asset/art/animation/c02_吕萍_爬出洞口/7.png" id="177_30gav"] [ext_resource type="Texture2D" uid="uid://c07fs4qbytxl5" path="res://asset/art/animation/c02_吕萍_爬出洞口/7.png" id="177_30gav"]
[ext_resource type="Texture2D" uid="uid://y0uw5c7ct8ur" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/7.png" id="177_i14wq"]
[ext_resource type="Texture2D" uid="uid://k6llq8hpv01n" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/8.png" id="178_f3qey"]
[ext_resource type="Texture2D" uid="uid://dpbssds2oybf3" path="res://asset/art/animation/c02_吕萍_爬出洞口/8.png" id="178_lq4xp"] [ext_resource type="Texture2D" uid="uid://dpbssds2oybf3" path="res://asset/art/animation/c02_吕萍_爬出洞口/8.png" id="178_lq4xp"]
[ext_resource type="Texture2D" uid="uid://b6sxtlyy0dbja" path="res://asset/art/animation/c02_吕萍_爬出洞口/9.png" id="179_anj58"] [ext_resource type="Texture2D" uid="uid://b6sxtlyy0dbja" path="res://asset/art/animation/c02_吕萍_爬出洞口/9.png" id="179_anj58"]
[ext_resource type="Texture2D" uid="uid://1up7fjmk3ddc" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/9.png" id="179_c8ls2"]
[ext_resource type="Texture2D" uid="uid://cflqf0s244sc5" path="res://asset/art/animation/c02_吕萍_爬出洞口/10.png" id="180_eoab0"] [ext_resource type="Texture2D" uid="uid://cflqf0s244sc5" path="res://asset/art/animation/c02_吕萍_爬出洞口/10.png" id="180_eoab0"]
[ext_resource type="Texture2D" uid="uid://dv1eo3buk6080" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/10.png" id="180_qwyrt"]
[ext_resource type="Texture2D" uid="uid://cf800nfyjliro" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右2.png" id="181_5p4j7"] [ext_resource type="Texture2D" uid="uid://cf800nfyjliro" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右2.png" id="181_5p4j7"]
[ext_resource type="Texture2D" uid="uid://clh0ig3gafmb1" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/11.png" id="181_geoqx"]
[ext_resource type="Texture2D" uid="uid://catelnwqsabkh" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右3.png" id="182_8yidt"] [ext_resource type="Texture2D" uid="uid://catelnwqsabkh" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右3.png" id="182_8yidt"]
[ext_resource type="Texture2D" uid="uid://bwksfenwfrrjd" path="res://asset/art/animation/c01_小小蝶_拿鸡毛掸子/12.png" id="182_jn1u0"]
[ext_resource type="Texture2D" uid="uid://bchdr32516ia6" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右4.png" id="183_2f5hc"] [ext_resource type="Texture2D" uid="uid://bchdr32516ia6" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右4.png" id="183_2f5hc"]
[ext_resource type="Texture2D" uid="uid://dja6nhonr0jvy" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右5.png" id="184_jrug8"] [ext_resource type="Texture2D" uid="uid://dja6nhonr0jvy" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右5.png" id="184_jrug8"]
[ext_resource type="Texture2D" uid="uid://bhahvevelyflk" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右6.png" id="185_in30h"] [ext_resource type="Texture2D" uid="uid://bhahvevelyflk" path="res://asset/art/animation/c02_吕萍_看小猫玩具_right/看玩具动作右6.png" id="185_in30h"]
@ -943,22 +985,51 @@ animations = [{
}, { }, {
"frames": [{ "frames": [{
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("123_ip1br") "texture": ExtResource("123_1rifq")
}, { }, {
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("124_ufqlo") "texture": ExtResource("124_f05ht")
}, { }, {
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("125_ftpsa") "texture": ExtResource("125_bxjt8")
}, { }, {
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("126_q6eiw") "texture": ExtResource("126_yy7k4")
}, { }, {
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("127_fucof") "texture": ExtResource("127_riraf")
}, { }, {
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("128_6ydk7") "texture": ExtResource("128_r5txh")
}, {
"duration": 1.0,
"texture": ExtResource("129_8qeg7")
}, {
"duration": 1.0,
"texture": ExtResource("130_lpb6w")
}],
"loop": true,
"name": &"c01_小小蝶_walking 8帧-317px高",
"speed": 6.0
}, {
"frames": [{
"duration": 1.0,
"texture": ExtResource("131_w281a")
}, {
"duration": 1.0,
"texture": ExtResource("132_eeag4")
}, {
"duration": 1.0,
"texture": ExtResource("133_fpldy")
}, {
"duration": 1.0,
"texture": ExtResource("134_x6ki2")
}, {
"duration": 1.0,
"texture": ExtResource("135_5fneh")
}, {
"duration": 1.0,
"texture": ExtResource("136_rej31")
}], }],
"loop": true, "loop": true,
"name": &"c01_小小蝶_walking_l", "name": &"c01_小小蝶_walking_l",
@ -989,6 +1060,82 @@ animations = [{
}, { }, {
"frames": [{ "frames": [{
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("135_hth06")
}, {
"duration": 1.0,
"texture": ExtResource("136_ko460")
}, {
"duration": 1.0,
"texture": ExtResource("137_1k3xv")
}, {
"duration": 1.0,
"texture": ExtResource("138_s23im")
}, {
"duration": 1.0,
"texture": ExtResource("139_xn4xi")
}, {
"duration": 1.0,
"texture": ExtResource("140_sr1sq")
}, {
"duration": 1.0,
"texture": ExtResource("141_sutp8")
}, {
"duration": 1.0,
"texture": ExtResource("142_ituys")
}, {
"duration": 1.0,
"texture": ExtResource("143_2aqu1")
}, {
"duration": 1.0,
"texture": ExtResource("144_m77af")
}, {
"duration": 1.0,
"texture": ExtResource("145_3wuv4")
}],
"loop": true,
"name": &"c01_小小蝶_侧面下蹲",
"speed": 6.0
}, {
"frames": [{
"duration": 1.0,
"texture": ExtResource("146_glua7")
}, {
"duration": 1.0,
"texture": ExtResource("147_jn0hd")
}, {
"duration": 1.0,
"texture": ExtResource("148_gtwc1")
}, {
"duration": 1.0,
"texture": ExtResource("149_ahx2r")
}, {
"duration": 1.0,
"texture": ExtResource("150_e3kfb")
}, {
"duration": 1.0,
"texture": ExtResource("151_p6hft")
}, {
"duration": 1.0,
"texture": ExtResource("152_aeo40")
}, {
"duration": 1.0,
"texture": ExtResource("153_a380e")
}, {
"duration": 1.0,
"texture": ExtResource("154_3io2u")
}, {
"duration": 1.0,
"texture": ExtResource("155_rya2f")
}, {
"duration": 1.0,
"texture": ExtResource("156_nj42l")
}],
"loop": true,
"name": &"c01_小小蝶_床上看书",
"speed": 6.0
}, {
"frames": [{
"duration": 1.0,
"texture": ExtResource("135_h2mh7") "texture": ExtResource("135_h2mh7")
}, { }, {
"duration": 1.0, "duration": 1.0,
@ -1041,6 +1188,47 @@ animations = [{
}, { }, {
"frames": [{ "frames": [{
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("171_4j5x4")
}, {
"duration": 1.0,
"texture": ExtResource("172_f0811")
}, {
"duration": 1.0,
"texture": ExtResource("173_yiq1s")
}, {
"duration": 1.0,
"texture": ExtResource("174_qoowv")
}, {
"duration": 1.0,
"texture": ExtResource("175_75miw")
}, {
"duration": 1.0,
"texture": ExtResource("176_sre1c")
}, {
"duration": 1.0,
"texture": ExtResource("177_i14wq")
}, {
"duration": 1.0,
"texture": ExtResource("178_f3qey")
}, {
"duration": 1.0,
"texture": ExtResource("179_c8ls2")
}, {
"duration": 1.0,
"texture": ExtResource("180_qwyrt")
}, {
"duration": 1.0,
"texture": ExtResource("181_geoqx")
}, {
"duration": 1.0,
"texture": ExtResource("182_jn1u0")
}],
"loop": false,
"name": &"c01_小小蝶_拿鸡毛掸子",
"speed": 6.0
}, {
"frames": [{
"duration": 1.0,
"texture": ExtResource("55_vb76q") "texture": ExtResource("55_vb76q")
}, { }, {
"duration": 1.0, "duration": 1.0,
@ -1739,7 +1927,7 @@ animations = [{
"duration": 1.0, "duration": 1.0,
"texture": ExtResource("237_uq1s2") "texture": ExtResource("237_uq1s2")
}], }],
"loop": true, "loop": false,
"name": &"c02_吕萍_风吹过", "name": &"c02_吕萍_风吹过",
"speed": 6.0 "speed": 6.0
}, { }, {

View File

@ -35,6 +35,8 @@ var reload_lock := Mutex.new()
func reload_frames(): func reload_frames():
# 暂不启用,使用手动调整
# return
var sprite_frames = animated_sprite.sprite_frames as SpriteFrames var sprite_frames = animated_sprite.sprite_frames as SpriteFrames
# {"path": "", "frames": {}, "ids": []} # {"path": "", "frames": {}, "ids": []}
var frames_data = frames_config.data.dirs[frame_dir_name] var frames_data = frames_config.data.dirs[frame_dir_name]

View File

@ -1,8 +1,17 @@
[gd_resource type="Theme" load_steps=5 format=3 uid="uid://j42sexotwnvk"] [gd_resource type="Theme" load_steps=8 format=3 uid="uid://j42sexotwnvk"]
[ext_resource type="Texture2D" uid="uid://bucpmiscjaem0" path="res://asset/art/ui/对话框.png" id="1_ddnwm"]
[ext_resource type="FontFile" uid="uid://bohyohbujly5f" path="res://asset/font/字体/方正楷体简体.TTF" id="1_hne2w"] [ext_resource type="FontFile" uid="uid://bohyohbujly5f" path="res://asset/font/字体/方正楷体简体.TTF" id="1_hne2w"]
[ext_resource type="FontFile" uid="uid://c4xo4de2eokky" path="res://asset/font/字体/三极行楷简体-粗.ttf" id="1_u1bqr"] [ext_resource type="FontFile" uid="uid://c4xo4de2eokky" path="res://asset/font/字体/三极行楷简体-粗.ttf" id="1_u1bqr"]
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_5sc16"]
texture = ExtResource("1_ddnwm")
texture_margin_left = 4.0
texture_margin_top = 4.0
texture_margin_right = 4.0
texture_margin_bottom = 4.0
region_rect = Rect2(22, 38, 40, 30)
[sub_resource type="FontVariation" id="FontVariation_d3ufv"] [sub_resource type="FontVariation" id="FontVariation_d3ufv"]
fallbacks = Array[Font]([ExtResource("1_u1bqr")]) fallbacks = Array[Font]([ExtResource("1_u1bqr")])
base_font = ExtResource("1_hne2w") base_font = ExtResource("1_hne2w")
@ -10,8 +19,14 @@ base_font = ExtResource("1_hne2w")
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_s8pgj"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_s8pgj"]
bg_color = Color(0.100338, 0.311042, 0.339945, 1) bg_color = Color(0.100338, 0.311042, 0.339945, 1)
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_nfon0"]
[resource] [resource]
default_font = SubResource("FontVariation_d3ufv") default_font = SubResource("FontVariation_d3ufv")
default_font_size = 12 default_font_size = 12
OptionButton/font_sizes/font_size = 10
PanelContainer/styles/panel = SubResource("StyleBoxTexture_5sc16")
PopupMenu/font_sizes/font_size = 16
dialog_container/base_type = &"MarginContainer" dialog_container/base_type = &"MarginContainer"
dialog_container/styles/panel = SubResource("StyleBoxFlat_s8pgj") dialog_container/styles/panel = SubResource("StyleBoxFlat_s8pgj")
empty_panel/styles/panel = SubResource("StyleBoxEmpty_nfon0")

View File

@ -1,3 +1,4 @@
@tool
extends Node extends Node
signal archive_loaded signal archive_loaded
@ -12,7 +13,7 @@ var archives: Array[int] # archive id list in ascending order
var autosave_timer := Timer.new() var autosave_timer := Timer.new()
func _ready() -> void: func _ready() -> void:
# 禁用默认退出行为,在 _notification 处理 NOTIFICATION_WM_CLOSE_REQUEST 时保存数据 # 禁用默认退出行为,在 _notification 处理 NOTIFICATION_WM_CLOSE_REQUEST 时保存数据
get_tree().set_auto_accept_quit(false) get_tree().set_auto_accept_quit(false)
if not _check_dirs_and_archives(): if not _check_dirs_and_archives():
@ -65,15 +66,21 @@ func _on_archive_id_changed():
archive_loaded.emit() archive_loaded.emit()
func _check_autosave_options(): func check_autosave_options():
if archive and GlobalConfigManager.config.auto_save_seconds > 1: if not GlobalConfigManager.config.auto_save_enabled:
autosave_timer.stop()
elif archive and GlobalConfigManager.config.auto_save_seconds > 1:
# reset left time # reset left time
autosave_timer.stop() autosave_timer.stop()
autosave_timer.one_shot = false autosave_timer.one_shot = false
autosave_timer.wait_time = GlobalConfigManager.config.auto_save_seconds autosave_timer.wait_time = GlobalConfigManager.config.auto_save_seconds
autosave_timer.start() autosave_timer.start()
else: if GlobalConfig.DEBUG:
autosave_timer.stop() print(
"check_autosave_options:",
GlobalConfigManager.config.auto_save_enabled,
autosave_timer.wait_time
)
func _try_auto_save(): func _try_auto_save():
@ -144,7 +151,7 @@ func save_all() -> void:
if archive: if archive:
ResourceSaver.save(archive) ResourceSaver.save(archive)
# reset autosave timer # reset autosave timer
_check_autosave_options() check_autosave_options()
func load_config() -> void: func load_config() -> void:
@ -161,7 +168,8 @@ func load_config() -> void:
GlobalConfigManager.config.resource_path = path GlobalConfigManager.config.resource_path = path
# connect signals # connect signals
GlobalConfigManager.config.current_selected_archive_id_changed.connect(_on_archive_id_changed) GlobalConfigManager.config.current_selected_archive_id_changed.connect(_on_archive_id_changed)
GlobalConfigManager.config.auto_save_seconds_changed.connect(_check_autosave_options) GlobalConfigManager.config.auto_save_seconds_changed.connect(check_autosave_options)
GlobalConfigManager.config.auto_save_enabled_changed.connect(check_autosave_options)
func load_archive() -> void: func load_archive() -> void:
@ -176,7 +184,7 @@ func load_archive() -> void:
_handle_load_error(str(selected_id) + " 号存档", "加载") _handle_load_error(str(selected_id) + " 号存档", "加载")
return return
archive.resource_path = path archive.resource_path = path
_check_autosave_options() check_autosave_options()
func _handle_load_error(target, action) -> void: func _handle_load_error(target, action) -> void:

View File

@ -7,16 +7,15 @@ const DEBUG = true
const RES_FILE_FORMAT = ".tres" const RES_FILE_FORMAT = ".tres"
## layers ## layers
const CANVAS_LAYER_DIALOG = 13 const CANVAS_LAYER_DIALOG = 23
const CANVAS_LAYER_UI = 12 const CANVAS_LAYER_UI = 22
const CANVAS_LAYER_PROP_INSPECTOR = 11 const CANVAS_LAYER_PROP_INSPECTOR = 21
const CANVAS_LAYER_SETTINGS = 20
const CANVAS_LAYER_BAG = 11
const CANVAS_LAYER_SHADING = 10 const CANVAS_LAYER_SHADING = 10
const CANVAS_LAYER_FG = 2 const CANVAS_LAYER_FG = 2
const CANVAS_LAYER_HD_ENTITY = 1 const CANVAS_LAYER_HD_ENTITY = 1
const AUDIO_BUS_SFX = "game_sfx"
const CHARACTER_COLOR_MAP = { const CHARACTER_COLOR_MAP = {
"default": Color.LIGHT_SEA_GREEN, "default": Color.LIGHT_SEA_GREEN,
"吕萍": Color.ORANGE, "吕萍": Color.ORANGE,
@ -33,6 +32,7 @@ const CHARACTER_COLOR_MAP = {
} }
signal current_selected_archive_id_changed signal current_selected_archive_id_changed
signal auto_save_enabled_changed
signal auto_save_seconds_changed signal auto_save_seconds_changed
@export var game_total_seconds := 0 # 游戏总时长 @export var game_total_seconds := 0 # 游戏总时长
@ -41,7 +41,18 @@ signal auto_save_seconds_changed
set(val): set(val):
current_selected_archive_id = val current_selected_archive_id = val
current_selected_archive_id_changed.emit() current_selected_archive_id_changed.emit()
@export var auto_save_enabled := true:
set(val):
auto_save_enabled = val
auto_save_enabled_changed.emit()
@export var auto_save_seconds := 60: @export var auto_save_seconds := 60:
set(val): set(val):
auto_save_seconds = val auto_save_seconds = val
auto_save_seconds_changed.emit() auto_save_seconds_changed.emit()
# window
@export var window_fullscreen := false
@export var window_top := true
# sound
@export var db_master := 0.0
@export var db_dialog := 0.0
@export var db_game_sfx := 0.0

View File

@ -1,9 +1,12 @@
@tool
extends Node extends Node
var config: GlobalConfig var config: GlobalConfig:
set = _set_config
var timer = Timer.new() var timer = Timer.new()
func _ready() -> void: func _ready() -> void:
timer.wait_time = 5 timer.wait_time = 5
timer.one_shot = false timer.one_shot = false
@ -12,6 +15,20 @@ func _ready() -> void:
timer.start() timer.start()
func _set_config(val: GlobalConfig) -> void:
config = val
# set up window
if config.window_fullscreen:
get_window().mode = Window.MODE_FULLSCREEN
else:
get_window().mode = Window.MODE_WINDOWED
get_window().always_on_top = config.window_top
# set up sound
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), config.db_master)
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("game_sfx"), config.db_game_sfx)
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("dialog"), config.db_dialog)
func _on_timer_timeout(): func _on_timer_timeout():
var archive = ArchiveManager.archive var archive = ArchiveManager.archive
if archive: if archive:

View File

@ -7,25 +7,168 @@ enum VIBE {
TOUCHING, TOUCHING,
} }
@export var first_entered = true
var prop_bag_instance = preload("res://scene/prop/prop_bag.tscn").instantiate()
func _ready() -> void:
add_child(prop_bag_instance)
prop_bag_instance.visible = false
#### Ground and Loader ####
func get_ground_loader() -> GroundLoader:
return get_node_or_null("/root/Main/GroundLoader") as GroundLoader
func get_ground() -> Ground2D:
var loader = get_ground_loader()
if loader:
return loader.ground
# 在 editor 编辑时ground 在 Section 节点下
var root = get_node("/root")
for child in root.get_children():
if child.name.begins_with("S0") or child.name.begins_with("S1"):
return child.get_node_or_null("Ground") as Ground2D
return null
func get_camera_marker(): func get_camera_marker():
return get_node_or_null("/root/Main/CameraFocusMarker") var ground = get_ground()
if ground:
return ground.camera_focus_marker
return null
func get_player() -> MainPlayer: func get_player() -> MainPlayer:
var player = get_node_or_null("/root/Main/GroundLoader/Ground/MainPlayer") as MainPlayer var ground = get_ground()
# 在 editor 编辑时,可能会在 grounds 文件下获得 player if ground:
if not player: return ground.player
var root = get_parent() return null
for child in root.get_children():
if child.name.begins_with("S0") or child.name.begins_with("S1"):
player = child.get_node_or_null("Ground/MainPlayer") as MainPlayer func focus_nodepath(node_path: NodePath) -> void:
break if not node_path:
return player printerr("Node path is empty")
return
var node = get_node_or_null(node_path)
if node:
focus_node(node)
else:
printerr("Node not found:", node_path)
func focus_node(node: CanvasItem) -> void:
var ground = get_ground()
if ground:
ground.focus_node(node)
func focus_player() -> void:
var ground = get_ground()
if ground:
ground.focus_player()
func focus_player_and_reset_zoom(duration := .5) -> void:
var marker = get_camera_marker()
if marker:
marker.tween_zoom(1.0, duration).tween_callback(focus_player)
# action_locked 用于设置界面等强制锁定action_freezed 用于查看物品等锁定
# action_locked 优先级高于 action_freezed
# action_locked 对应 lock 与 unlock 方法
func lock_player():
var player = get_player()
if player:
player.action_locked = true
func unlock_player():
var player = get_player()
if player:
player.action_locked = false
# action_freezed 对应 freeze 与 release 方法
# lock_time: the time to lock the player action. 0 means lock forever, thus the player will be locked until release_player is called.
func freeze_player(
lock_time: float, action := PlayerAnimationConfig.ACTION_NONE, auto_quit := false
) -> void:
var player = get_player()
if player:
player.freeze_player(lock_time, action, auto_quit)
else:
printerr("Player node not found")
func freeze_and_play(lock_time: float, animation := "", auto_quit := false) -> void:
var player = get_player()
if player:
player.freeze_and_play(lock_time, animation, auto_quit)
else:
printerr("Player node not found")
func release_player():
var player = get_player()
if player:
player.release_player()
else:
printerr("Player node not found")
func set_camera_boundary(rect: Rect2) -> void:
var camera_marker = get_camera_marker()
camera_marker.limit_left = rect.position.x
camera_marker.limit_right = rect.position.x + rect.size.x
camera_marker.limit_top = rect.position.y
camera_marker.limit_bottom = rect.position.y + rect.size.y
func set_player_boundary(rect: Rect2) -> void:
var player = get_player()
if player:
player.player_movement_rect = rect
else:
printerr("Player node not found")
#### Prop ####
var hud_path = ""
func get_prop_hud() -> PropHud: func get_prop_hud() -> PropHud:
return get_node_or_null("/root/Main/UILayer/PropHUD") as PropHud var hud = get_node_or_null("/root/Main/UILayer/PropHUD") as PropHud
if hud:
return hud
if hud_path:
hud = get_node_or_null(hud_path) as PropHud
if hud:
return hud
else:
hud_path = ""
# 如果在 debug 模式从其他场景启动,没有 HUD 但又要获取,就新建 hud 放进场景
var ground = get_ground()
if ground:
var parent = ground.get_parent()
if parent:
var layer = CanvasLayer.new()
layer.layer = GlobalConfig.CANVAS_LAYER_UI
layer.name = "UILayer"
hud = preload("res://scene/prop/prop_hud.tscn").instantiate()
hud.name = "PropHUD"
layer.add_child(hud)
hud.inventory = ArchiveManager.archive.prop_inventory
parent.call_deferred("add_child", layer)
hud_path = str(parent.get_path()) + "/UILayer/PropHUD"
print("New HUD path:", hud_path)
return hud
func get_current_prop(must_selected: bool) -> String: func get_current_prop(must_selected: bool) -> String:
@ -55,43 +198,6 @@ func pop_os(lines := []):
printerr("Player node not found") printerr("Player node not found")
# lock_time: the time to lock the player action. 0 means lock forever, thus the player will be locked until release_player is called.
func freeze_player(lock_time: float, animation := "", loop := false, offset := Vector2(0, 0)) -> void:
var player = get_player()
if player:
player.freeze_player(lock_time, animation, loop, offset)
else:
printerr("Player node not found")
func release_player():
var player = get_player()
if player:
player.release_player()
else:
printerr("Player node not found")
func set_camera_boundary(rect: Rect2) -> void:
var camera_marker = CameraFocusMarker
camera_marker.limit_left = rect.position.x
camera_marker.limit_right = rect.position.x + rect.size.x
camera_marker.limit_top = rect.position.y
camera_marker.limit_bottom = rect.position.y + rect.size.y
func set_player_boundary(rect: Rect2) -> void:
var player = get_player()
if player:
player.player_movement_rect = rect
else:
printerr("Player node not found")
func get_ground_loader() -> GroundLoader:
return get_node_or_null("/root/Main/GroundLoader") as GroundLoader
func pop_notification(msg: String, number := 1) -> void: func pop_notification(msg: String, number := 1) -> void:
var notification_node = get_node_or_null("/root/Main/UILayer/Notification") var notification_node = get_node_or_null("/root/Main/UILayer/Notification")
if notification_node: if notification_node:
@ -126,58 +232,25 @@ func get_inspector() -> PropInspector:
return get_node_or_null("/root/Main/PropInspector") as PropInspector return get_node_or_null("/root/Main/PropInspector") as PropInspector
func focus_nodepath(node_path: NodePath) -> void: func checkout_index_page():
if not node_path: ArchiveManager.save_all()
printerr("Node path is empty") # get_tree().change_scene_to_file("res://scene/index_page.tscn")
return get_tree().change_scene_to_packed(preload("res://scene/index_page.tscn"))
var node = get_node_or_null(node_path)
if node:
focus_node(node)
else:
printerr("Node not found:", node_path)
var camera_remote_transformer: RemoteTransform2D func show_bag():
var focus_mutex := Mutex.new() freeze_player(0)
prop_bag_instance.visible = true
func focus_node(node: CanvasItem) -> void: func hide_bag():
var rt := node.get_node_or_null("./camera_remote_transformer") as RemoteTransform2D release_player()
focus_mutex.lock() prop_bag_instance.visible = false
if rt:
if camera_remote_transformer and rt != camera_remote_transformer:
camera_remote_transformer.queue_free()
camera_remote_transformer = rt
else:
if camera_remote_transformer:
camera_remote_transformer.queue_free()
camera_remote_transformer = RemoteTransform2D.new()
node.add_child(camera_remote_transformer)
_setup_camera_remote_transformer()
focus_mutex.unlock()
func _setup_camera_remote_transformer(): func quit_game():
if not camera_remote_transformer: ArchiveManager.save_all()
return get_tree().quit()
camera_remote_transformer.remote_path = "/root/CameraFocusMarker"
camera_remote_transformer.update_position = true
camera_remote_transformer.update_rotation = false
camera_remote_transformer.update_scale = false
camera_remote_transformer.name = "camera_remote_transformer"
func focus_player(player: MainPlayer = null) -> void:
if not player:
player = get_player()
if player:
focus_node(player)
else:
printerr("Player node not found")
func focus_player_and_reset_zoom(duration := 1.0) -> void:
CameraFocusMarker.tween_zoom(1.0, duration).tween_callback(focus_player)
# func player_moved_delta_x(delta_x: float) -> void: # func player_moved_delta_x(delta_x: float) -> void:
# # fog effect offset # # fog effect offset

View File

@ -26,7 +26,7 @@ config/name_localized={
"zh_Hans": "衔蝶", "zh_Hans": "衔蝶",
"zh_Hant": "衔蝶" "zh_Hant": "衔蝶"
} }
run/main_scene="res://scene/main.tscn" run/main_scene="res://scene/index_page.tscn"
config/features=PackedStringArray("4.3", "Mobile") config/features=PackedStringArray("4.3", "Mobile")
config/icon="res://icon.svg" config/icon="res://icon.svg"
@ -40,8 +40,6 @@ DebugMenu="*res://addons/debug_menu/debug_menu.tscn"
DialogueManager="*res://addons/dialogue_manager/dialogue_manager.gd" DialogueManager="*res://addons/dialogue_manager/dialogue_manager.gd"
GlobalConfigManager="*res://manager/config_manager/global_config_manager.gd" GlobalConfigManager="*res://manager/config_manager/global_config_manager.gd"
ArchiveManager="*res://manager/archive_manager/archive_manager.gd" ArchiveManager="*res://manager/archive_manager/archive_manager.gd"
CameraFocusMarker="*res://scene/camera/camera_focus_marker.tscn"
MainCamera="*res://scene/camera/main_camera.tscn"
SceneManager="*res://manager/deploy/scene/scene_manager.gd" SceneManager="*res://manager/deploy/scene/scene_manager.gd"
AudioManager="*res://manager/audio_manager/audio_manager.gd" AudioManager="*res://manager/audio_manager/audio_manager.gd"
EventManager="*res://manager/event_manager/event_manager.gd" EventManager="*res://manager/event_manager/event_manager.gd"
@ -151,6 +149,16 @@ toggle_journal={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
] ]
} }
escape={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
bag={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":98,"location":0,"echo":false,"script":null)
]
}
[internationalization] [internationalization]

View File

@ -1,16 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://cqkeegrcdjyg4"]
[ext_resource type="Script" path="res://scene/camera/camera_focus_marker.gd" id="1_7t4e6"]
[node name="CameraFocusMarker" type="Marker2D"]
script = ExtResource("1_7t4e6")
lock_horizontal = null
speed = null
half_screen_size = null
limit_left = null
limit_right = null
limit_top = null
limit_bottom = null
[node name="Target" type="Node2D" parent="."]
unique_name_in_owner = true

View File

@ -1 +0,0 @@
extends Camera2D

View File

@ -1,6 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://ogyvstscr0kx"]
[ext_resource type="Script" path="res://scene/camera/main_camera.gd" id="1_pwiuw"]
[node name="MainCamera" type="Camera2D"]
script = ExtResource("1_pwiuw")

View File

@ -164,7 +164,7 @@ mouse_filter = 1
text = "Response example" text = "Response example"
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
volume_db = -15.0 bus = &"dialog"
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"] [connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
[connection signal="response_selected" from="Balloon/Responses/ResponsesMenu" to="." method="_on_responses_menu_response_selected"] [connection signal="response_selected" from="Balloon/Responses/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]

View File

@ -3,6 +3,11 @@ extends Node2D
signal player_entered signal player_entered
@export_enum("enter", "interact") var trigger_mode := "enter":
set(val):
trigger_mode = val
if is_node_ready():
_check_sign_display()
@export var one_shot := true @export var one_shot := true
# 首次进入 tree 就直接启用 # 首次进入 tree 就直接启用
@export var on_first_enter_tree := false @export var on_first_enter_tree := false
@ -32,9 +37,10 @@ var played_time := 0.0
# ground_archive.set_pair(name, "played", played) # ground_archive.set_pair(name, "played", played)
# played = val # played = val
@onready var area2d = %Area2D as Area2D @onready var sign_marker := %Sign as Sign
@onready var area := %Area2D as Area2D
@onready var ground_archive := ArchiveManager.archive.ground_archive() @onready var ground_archive := ArchiveManager.archive.ground_archive()
@onready var played = ground_archive.get_value(name, "played", false): @onready var played: bool = ground_archive.get_value(name, "played", false):
set(val): set(val):
played = val played = val
ground_archive.set_pair(name, "played", played) ground_archive.set_pair(name, "played", played)
@ -48,13 +54,19 @@ func _ready() -> void:
animation_player.animation_libraries_updated.connect(notify_property_list_changed) animation_player.animation_libraries_updated.connect(notify_property_list_changed)
if Engine.is_editor_hint(): if Engine.is_editor_hint():
return return
_check_sign_display()
if one_shot and played: if one_shot and played:
if GlobalConfig.DEBUG: if GlobalConfig.DEBUG:
print("Ambush already played, name=", name) print("Ambush already played, name=", name)
return return
if on_first_enter_tree: if on_first_enter_tree:
_entered(null) _entered(null)
area2d.body_entered.connect(_entered) sign_marker.interacted.connect(_interacted)
area.body_entered.connect(_entered)
func _check_sign_display():
sign_marker.show_sign = trigger_mode == "interact" and (not one_shot or not played)
func _get_animation_player() -> AnimationPlayer: func _get_animation_player() -> AnimationPlayer:
@ -64,7 +76,17 @@ func _get_animation_player() -> AnimationPlayer:
var enter_mutex = Mutex.new() var enter_mutex = Mutex.new()
func _entered(_body): func _interacted():
if trigger_mode == "interact":
_do_trigger()
func _entered(_body = null):
if trigger_mode == "enter":
_do_trigger()
func _do_trigger():
var time = Time.get_ticks_msec() var time = Time.get_ticks_msec()
# 确保只有一个线程进入该逻辑,因为有时 player 碰撞和首次进入 tree 都会触发该方法 # 确保只有一个线程进入该逻辑,因为有时 player 碰撞和首次进入 tree 都会触发该方法
if not enter_mutex.try_lock(): if not enter_mutex.try_lock():
@ -89,13 +111,14 @@ func _entered(_body):
# hook_dialogue # hook_dialogue
if hook_dialogue_title: if hook_dialogue_title:
if lock_player_on_playing_dialogue: if lock_player_on_playing_dialogue:
SceneManager.freeze_player(0.0, "") SceneManager.freeze_player(0.0)
DialogueManager.show_dialogue_balloon(dialogue_res, hook_dialogue_title) DialogueManager.show_dialogue_balloon(dialogue_res, hook_dialogue_title)
DialogueManager.dialogue_ended.connect(_on_dialogue_ended, CONNECT_ONE_SHOT) DialogueManager.dialogue_ended.connect(_on_dialogue_ended, CONNECT_ONE_SHOT)
player_entered.emit() player_entered.emit()
if GlobalConfig.DEBUG: if GlobalConfig.DEBUG:
print("ambush body_entered!") print("ambush body_entered!")
enter_mutex.unlock() enter_mutex.unlock()
_check_sign_display()
func _on_dialogue_ended(_res): func _on_dialogue_ended(_res):

View File

@ -1,16 +1,20 @@
[gd_scene load_steps=3 format=3 uid="uid://bnf3lkcbpx1ar"] [gd_scene load_steps=4 format=3 uid="uid://bnf3lkcbpx1ar"]
[ext_resource type="Script" path="res://scene/entity/ambush.gd" id="1_rxgbr"] [ext_resource type="Script" path="res://scene/entity/ambush.gd" id="1_rxgbr"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="2_n51wc"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_iwrfx"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_iwrfx"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(10, 70) size = Vector2(10, 70)
[node name="Ambush" type="Node2D"] [node name="Ambush" type="Sprite2D"]
script = ExtResource("1_rxgbr") script = ExtResource("1_rxgbr")
hook_dialogue_title = "" hook_dialogue_title = ""
hook_animation = "" hook_animation = ""
[node name="Sign" parent="." instance=ExtResource("2_n51wc")]
unique_name_in_owner = true
[node name="Area2D" type="Area2D" parent="."] [node name="Area2D" type="Area2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -102,7 +102,7 @@ func _on_interacted() -> void:
_on_cancel() _on_cancel()
return return
interacted = true interacted = true
CameraFocusMarker.tween_zoom(1.8, 1.5) SceneManager.get_camera_marker().tween_zoom(1.8)
SceneManager.focus_node(self) SceneManager.focus_node(self)
# DialogueManager.show_dialogue_balloon(dialog, "diyizhang_01_03_mimi3") # DialogueManager.show_dialogue_balloon(dialog, "diyizhang_01_03_mimi3")

View File

@ -17,7 +17,7 @@ region = Rect2(480, 468, 63, 63)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_8d3b4"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_8d3b4"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(35, 70) size = Vector2(10, 70)
[node name="Interactable" type="Sprite2D"] [node name="Interactable" type="Sprite2D"]
script = ExtResource("1_6nrd3") script = ExtResource("1_6nrd3")

View File

@ -73,10 +73,10 @@ func _on_interacted() -> void:
sfx.play() sfx.play()
inspected_time = Time.get_ticks_msec() inspected_time = Time.get_ticks_msec()
SceneManager.focus_node(self) SceneManager.focus_node(self)
CameraFocusMarker.tween_zoom(2.0, 1.5) SceneManager.get_camera_marker().tween_zoom(2.0)
status = STATUS_INSPECTING_COVER status = STATUS_INSPECTING_COVER
sign_mark.show_sign = false sign_mark.show_sign = false
SceneManager.freeze_player(0) SceneManager.freeze_player(0.0, PlayerAnimationConfig.ACTION_LOOKUP_WALL)
cover_rect.texture = texture_cover cover_rect.texture = texture_cover
tip_label.text = tip_cover tip_label.text = tip_cover
_blink_label(true) _blink_label(true)
@ -115,7 +115,7 @@ func _on_cancel(_body = null):
if blinking_tween and blinking_tween.is_running(): if blinking_tween and blinking_tween.is_running():
blinking_tween.kill() blinking_tween.kill()
tween.parallel().tween_property(tip_label, "modulate:a", 0.0, 0.15) tween.parallel().tween_property(tip_label, "modulate:a", 0.0, 0.15)
SceneManager.focus_player_and_reset_zoom(1.0) SceneManager.focus_player_and_reset_zoom()
SceneManager.release_player() SceneManager.release_player()
sign_mark.show_sign = true sign_mark.show_sign = true

View File

@ -5,7 +5,7 @@
[ext_resource type="AudioStream" uid="uid://csdwhc83jshd3" path="res://asset/audio/sfx/ui/纸条.mp3" id="3_3ldx7"] [ext_resource type="AudioStream" uid="uid://csdwhc83jshd3" path="res://asset/audio/sfx/ui/纸条.mp3" id="3_3ldx7"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/tool/neutral_point_light.webp" id="3_o562w"] [ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/tool/neutral_point_light.webp" id="3_o562w"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_do8tr"] [ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_do8tr"]
[ext_resource type="SpriteFrames" uid="uid://bvypjkvdwysx8" path="res://config/animation/entity_sprite_frames.tres" id="6_e77p4"] [ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="6_e77p4"]
[ext_resource type="Script" path="res://scene/entity/ux/animated_sound_sprite_2d.gd" id="7_bhwlx"] [ext_resource type="Script" path="res://scene/entity/ux/animated_sound_sprite_2d.gd" id="7_bhwlx"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]
@ -54,7 +54,7 @@ unique_name_in_owner = true
shape = SubResource("RectangleShape2D_4fuic") shape = SubResource("RectangleShape2D_4fuic")
[node name="InspectLayer" type="CanvasLayer" parent="."] [node name="InspectLayer" type="CanvasLayer" parent="."]
layer = 11 layer = 21
[node name="Root" type="Control" parent="InspectLayer"] [node name="Root" type="Control" parent="InspectLayer"]
layout_mode = 3 layout_mode = 3
@ -63,8 +63,9 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
[node name="Container" type="PanelContainer" parent="InspectLayer/Root"] [node name="Container" type="MarginContainer" parent="InspectLayer/Root"]
unique_name_in_owner = true unique_name_in_owner = true
modulate = Color(1, 1, 1, 0) modulate = Color(1, 1, 1, 0)
layout_mode = 1 layout_mode = 1

View File

@ -78,15 +78,15 @@ func _show_os(res, title):
else: else:
break break
SceneManager.pop_os(lines) SceneManager.pop_os(lines)
SceneManager.freeze_player(1.0, "") SceneManager.freeze_player(1.0, PlayerAnimationConfig.ACTION_LOOKUP_WALL)
func _show_balloon(res, title): func _show_balloon(res, title):
# SceneManager.focus_node(self) # SceneManager.focus_node(self)
# CameraFocusMarker.tween_zoom(1.1, 1.5) # SceneManager.get_camera_marker().tween_zoom(1.1, 1.5)
DialogueManager.show_dialogue_balloon(res, title) DialogueManager.show_dialogue_balloon(res, title)
# TODO note viewing animation # TODO note viewing animation
SceneManager.freeze_player(0, "") SceneManager.freeze_player(0)
interacting = true interacting = true
DialogueManager.dialogue_ended.connect(_on_ballon_ended, CONNECT_ONE_SHOT) DialogueManager.dialogue_ended.connect(_on_ballon_ended, CONNECT_ONE_SHOT)
# var player = SceneManager.get_player() # var player = SceneManager.get_player()

View File

@ -4,10 +4,11 @@ class_name Sign extends Control
@export var show_sign := true: @export var show_sign := true:
set(val): set(val):
show_sign = val show_sign = val
if val: # 隐藏时强制设置透明度为 0显示时需要根据激活状态设置透明度
modulate.a = 1.0 if not val:
else:
modulate.a = 0.0 modulate.a = 0.0
elif activated:
modulate.a = 1.0
@export var draw_shadow := false @export var draw_shadow := false
signal interacted signal interacted
@ -124,16 +125,22 @@ func _unhandled_input(event: InputEvent) -> void:
# 传送时会导致 is_inside_tree 为 false此时也无需与 prop hud 抢占 focus # 传送时会导致 is_inside_tree 为 false此时也无需与 prop hud 抢占 focus
focus_mode = FOCUS_ALL focus_mode = FOCUS_ALL
grab_focus() grab_focus()
_set_handled()
elif event.is_action_pressed("cancel"): elif event.is_action_pressed("cancel"):
cancel.emit() cancel.emit()
_set_handled()
release_focus() release_focus()
var viewport = get_viewport()
if viewport:
viewport.set_input_as_handled() func _set_handled():
var viewport = get_viewport()
if viewport:
viewport.set_input_as_handled()
var shake_tween var shake_tween
# 使用无效道具,抖动提示 # 使用无效道具,抖动提示
func invalid_shake(): func invalid_shake():
if shake_tween: if shake_tween:

View File

@ -1,5 +1,6 @@
extends Marker2D class_name CameraFocusMarker extends Marker2D
@export var camera: Camera2D
@export_group("Status") @export_group("Status")
@export var lock_horizontal = true @export var lock_horizontal = true
@export_group("Config") @export_group("Config")
@ -19,12 +20,16 @@ extends Marker2D
@export var limit_bottom := 316.0 @export var limit_bottom := 316.0
@onready var target = %Target as Node2D @onready var target = %Target as Node2D
# @onready var camera = %MainCamera as MainCamera
var zoom_ratio := 1.0 var zoom_ratio := 1.0
var zoom_tween: Tween var zoom_tween: Tween
func _ready() -> void:
if not camera:
push_error("Camera2D node not found")
func tweak_position(velocity, facing_direction): func tweak_position(velocity, facing_direction):
var ideal_x = facing_direction.x * min(50.0, 0.5 * abs(velocity.x)) var ideal_x = facing_direction.x * min(50.0, 0.5 * abs(velocity.x))
var current_x = target.position.x var current_x = target.position.x
@ -39,9 +44,11 @@ func tweak_position(velocity, facing_direction):
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
if not camera:
return
# set camera's position # set camera's position
var target_position = target.global_position var target_position = target.global_position
var current_position = MainCamera.global_position var current_position = camera.global_position
# easing with speed # easing with speed
var position_delta = (target_position - current_position) * speed * delta var position_delta = (target_position - current_position) * speed * delta
var new_position = current_position + position_delta var new_position = current_position + position_delta
@ -50,11 +57,11 @@ func _physics_process(delta: float) -> void:
margin.y += shaded_height margin.y += shaded_height
new_position.x = clamp(new_position.x, limit_left + margin.x, limit_right - margin.x) new_position.x = clamp(new_position.x, limit_left + margin.x, limit_right - margin.x)
new_position.y = clamp(new_position.y, limit_top + margin.y, limit_bottom - margin.y) new_position.y = clamp(new_position.y, limit_top + margin.y, limit_bottom - margin.y)
MainCamera.global_position = new_position camera.global_position = new_position
MainCamera.zoom = Vector2(zoom_ratio, zoom_ratio) camera.zoom = Vector2(zoom_ratio, zoom_ratio)
func tween_zoom(ratio: float, duration := 1.0) -> Tween: func tween_zoom(ratio: float, duration := .7) -> Tween:
if zoom_tween and zoom_tween.is_running(): if zoom_tween and zoom_tween.is_running():
zoom_tween.kill() zoom_tween.kill()
zoom_tween = create_tween() zoom_tween = create_tween()
@ -68,3 +75,25 @@ func tween_zoom(ratio: float, duration := 1.0) -> Tween:
. set_ease(Tween.EASE_IN_OUT) . set_ease(Tween.EASE_IN_OUT)
) )
return zoom_tween return zoom_tween
var exited := false
var exit_position: Vector2
var enter_tree_tween: Tween
func _exit_tree() -> void:
exit_position = global_position
exited = true
func _enter_tree() -> void:
if exited:
if enter_tree_tween and enter_tree_tween.is_running():
enter_tree_tween.kill()
exited = false
global_position = exit_position
enter_tree_tween = create_tween()
enter_tree_tween.tween_property(self, "position", Vector2.ZERO, 0.2).set_trans(
Tween.TRANS_CUBIC
)

View File

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://cqkeegrcdjyg4"]
[ext_resource type="Script" path="res://scene/ground/camera/camera_focus_marker.gd" id="1_7t4e6"]
[node name="CameraFocusMarker" type="Marker2D"]
script = ExtResource("1_7t4e6")
[node name="Target" type="Node2D" parent="."]
unique_name_in_owner = true

View File

@ -24,6 +24,8 @@ var footstep_type: String = "concrete":
@onready var directional_light := %DirectionalLight2D as DirectionalLight2D @onready var directional_light := %DirectionalLight2D as DirectionalLight2D
@onready var bg_sprite = %BGSprite2D as Sprite2D @onready var bg_sprite = %BGSprite2D as Sprite2D
@onready var foreground = %ParallaxForeground as ParallaxBackground @onready var foreground = %ParallaxForeground as ParallaxBackground
@onready var camera_focus_marker = %CameraFocusMarker as CameraFocusMarker
@onready var camera = %Camera2D as Camera2D
@onready var footstep_audio = %FootstepAudioPlayer as RandomAudioStreamPlayer @onready var footstep_audio = %FootstepAudioPlayer as RandomAudioStreamPlayer
@ -47,10 +49,16 @@ func _ready() -> void:
return return
_set_camera_and_player_boundary() _set_camera_and_player_boundary()
_load_footstep_audio() _load_footstep_audio()
focus_player()
# %ColorRectTop.visible = true # %ColorRectTop.visible = true
# %ColorRectBottom.visible = true # %ColorRectBottom.visible = true
func _enter_tree() -> void:
if camera:
camera.enabled = true
func _reset_player_positon(): func _reset_player_positon():
player.position.y = player_y player.position.y = player_y
player.position.x = $DeployLayer/portal_left.position.x player.position.x = $DeployLayer/portal_left.position.x
@ -86,3 +94,25 @@ func _load_footstep_audio():
func play_footstep_sound() -> void: func play_footstep_sound() -> void:
if not footstep_audio.audio_collections.is_empty(): if not footstep_audio.audio_collections.is_empty():
footstep_audio.play_random() footstep_audio.play_random()
var focus_mutex := Mutex.new()
func get_player() -> MainPlayer:
return player
func focus_node(node: CanvasItem) -> void:
if node.is_ancestor_of(camera_focus_marker):
return
focus_mutex.lock()
var parent = camera_focus_marker.get_parent()
if parent:
parent.remove_child(camera_focus_marker)
node.add_child(camera_focus_marker)
focus_mutex.unlock()
func focus_player() -> void:
focus_node(player)

View File

@ -1,8 +1,9 @@
[gd_scene load_steps=7 format=3 uid="uid://dayyx4jerj7io"] [gd_scene load_steps=8 format=3 uid="uid://dayyx4jerj7io"]
[ext_resource type="Script" path="res://scene/ground/ground.gd" id="1_0vrlo"] [ext_resource type="Script" path="res://scene/ground/ground.gd" id="1_0vrlo"]
[ext_resource type="PackedScene" uid="uid://cjhw5ecygrqty" path="res://scene/player/main_player.tscn" id="3_atha7"] [ext_resource type="PackedScene" uid="uid://cjhw5ecygrqty" path="res://scene/player/main_player.tscn" id="3_atha7"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="3_t73yw"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="3_t73yw"]
[ext_resource type="PackedScene" uid="uid://cqkeegrcdjyg4" path="res://scene/ground/camera/camera_focus_marker.tscn" id="4_mgk0a"]
[ext_resource type="Script" path="res://config/audio/random_audio_stream_player.gd" id="5_7mb2q"] [ext_resource type="Script" path="res://config/audio/random_audio_stream_player.gd" id="5_7mb2q"]
[ext_resource type="Texture2D" uid="uid://by8h2yuqve7fw" path="res://asset/art/scene/c02/s06_院子回忆版/fg_有人.png" id="5_i5hii"] [ext_resource type="Texture2D" uid="uid://by8h2yuqve7fw" path="res://asset/art/scene/c02/s06_院子回忆版/fg_有人.png" id="5_i5hii"]
@ -52,6 +53,10 @@ portal_name = "right"
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2(26, 40) position = Vector2(26, 40)
[node name="CameraFocusMarker" parent="MainPlayer" node_paths=PackedStringArray("camera") instance=ExtResource("4_mgk0a")]
unique_name_in_owner = true
camera = NodePath("../../Camera2D")
[node name="ParallaxForeground" type="ParallaxBackground" parent="."] [node name="ParallaxForeground" type="ParallaxBackground" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
layer = 2 layer = 2
@ -94,3 +99,6 @@ height = 0.5
[node name="FootstepAudioPlayer" type="AudioStreamPlayer" parent="."] [node name="FootstepAudioPlayer" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
script = ExtResource("5_7mb2q") script = ExtResource("5_7mb2q")
[node name="Camera2D" type="Camera2D" parent="."]
unique_name_in_owner = true

View File

@ -20,6 +20,13 @@ func _default_data() -> Dictionary:
func _ready() -> void: func _ready() -> void:
# 等待 DeployLayer 先加载完成
var deploy_layer = get_node("../DeployLayer")
if deploy_layer:
if not deploy_layer.is_node_ready():
deploy_layer.ready.connect(_on_deploy_layer_ready)
else:
_on_deploy_layer_ready()
if Engine.is_editor_hint(): if Engine.is_editor_hint():
# notify_property_list_changed() # notify_property_list_changed()
# 更新 oneshot_animation 的可选项 # 更新 oneshot_animation 的可选项
@ -34,6 +41,10 @@ func _ready() -> void:
data[key] = archive_data[key] data[key] = archive_data[key]
func _on_deploy_layer_ready() -> void:
pass
func _notification(what: int) -> void: func _notification(what: int) -> void:
# 仅在首次进入场景时触发 # 仅在首次进入场景时触发
if what == NOTIFICATION_READY: if what == NOTIFICATION_READY:

View File

@ -1,6 +1,8 @@
@tool @tool
extends AnimationRoot extends AnimationRoot
var frame_relocated = false
# 覆盖该方法 # 覆盖该方法
func _default_data() -> Dictionary: func _default_data() -> Dictionary:
@ -10,3 +12,12 @@ func _default_data() -> Dictionary:
func _ready() -> void: func _ready() -> void:
super._ready() super._ready()
func _on_deploy_layer_ready() -> void:
var node = $"../DeployLayer/ambush鸡毛掸子"
# 画框
if node.played and node.one_shot:
frame_relocated = true
$"../DeployLayer/画框".rotation_degrees = 0.0
if GlobalConfig.DEBUG:
print("重置画框位置")

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=24 format=3 uid="uid://dlx5xxbg53rb8"] [gd_scene load_steps=27 format=3 uid="uid://dlx5xxbg53rb8"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_ff4yb"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_ff4yb"]
[ext_resource type="Script" path="res://scene/ground/scene/c01/s05_animation.gd" id="2_j5oim"] [ext_resource type="Script" path="res://scene/ground/scene/c01/s05_animation.gd" id="2_j5oim"]
@ -15,11 +15,197 @@
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="10_18v0g"] [ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="10_18v0g"]
[ext_resource type="Texture2D" uid="uid://diw7l2qdwbyoc" path="res://asset/art/scene/c01/s05_院长房间/e_画框.png" id="11_6gq1s"] [ext_resource type="Texture2D" uid="uid://diw7l2qdwbyoc" path="res://asset/art/scene/c01/s05_院长房间/e_画框.png" id="11_6gq1s"]
[ext_resource type="Texture2D" uid="uid://dx3ym8inpuj5b" path="res://asset/art/scene/c01/s05_院长房间/e_鸡毛掸子.png" id="12_jtglg"] [ext_resource type="Texture2D" uid="uid://dx3ym8inpuj5b" path="res://asset/art/scene/c01/s05_院长房间/e_鸡毛掸子.png" id="12_jtglg"]
[ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="14_e1bmq"]
[ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="14_lq1ou"] [ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="14_lq1ou"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="15_1uixh"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="15_1uixh"]
[ext_resource type="Texture2D" uid="uid://ox0ctin85kbl" path="res://asset/art/scene/c01/s05_院长房间/l_墙.png" id="16_qh7fg"] [ext_resource type="Texture2D" uid="uid://ox0ctin85kbl" path="res://asset/art/scene/c01/s05_院长房间/l_墙.png" id="16_qh7fg"]
[ext_resource type="Texture2D" uid="uid://bojbuuxwvlkkg" path="res://asset/art/scene/c01/s05_院长房间/l_窗户光源.png" id="17_qqw2v"] [ext_resource type="Texture2D" uid="uid://bojbuuxwvlkkg" path="res://asset/art/scene/c01/s05_院长房间/l_窗户光源.png" id="17_qqw2v"]
[sub_resource type="Animation" id="Animation_c6mhi"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("DeployLayer/使用鸡毛掸子:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(261, 42)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("DeployLayer/使用鸡毛掸子:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("DeployLayer/使用鸡毛掸子:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [false]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("DeployLayer/ambush鸡毛掸子:visible")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("MainPlayer:visible")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("DeployLayer/画框:rotation")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [-0.179769]
}
[sub_resource type="Animation" id="Animation_il8ov"]
resource_name = "使用鸡毛掸子"
length = 4.0
step = 0.02
capture_included = true
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("MainPlayer:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0.28, 3.48),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(261, 40), Vector2(261, 40)]
}
tracks/1/type = "method"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("MainPlayer")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.28),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [3.5, -1, true],
"method": &"freeze_player"
}]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("DeployLayer/画框:rotation")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(1.2, 2.44),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [-0.179974, 0.0]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("DeployLayer/使用鸡毛掸子:frame")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0.44, 3.18),
"transitions": PackedFloat32Array(1, 1),
"update": 2,
"values": [0, 11]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("DeployLayer/使用鸡毛掸子:position")
tracks/4/interp = 1
tracks/4/loop_wrap = false
tracks/4/keys = {
"times": PackedFloat32Array(0.28, 3.36),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(261, 42), Vector2(261, 42)]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("DeployLayer/使用鸡毛掸子:visible")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0.28, 3.36),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true, false]
}
tracks/6/type = "value"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath("MainPlayer:visible")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0.28, 3.36),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/7/type = "value"
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/path = NodePath("DeployLayer/ambush鸡毛掸子:visible")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
"times": PackedFloat32Array(0.02, 0.72, 2.82),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [true, false, true]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ifimj"]
_data = {
"RESET": SubResource("Animation_c6mhi"),
"使用鸡毛掸子": SubResource("Animation_il8ov")
}
[sub_resource type="RectangleShape2D" id="RectangleShape2D_6i5gw"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_6i5gw"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(40, 60) size = Vector2(40, 60)
@ -28,29 +214,32 @@ size = Vector2(40, 60)
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(10, 60) size = Vector2(10, 60)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_dq2na"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_5s1ih"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(10, 60) size = Vector2(10, 70)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_40ng7"]
resource_local_to_scene = true
size = Vector2(35, 70)
[node name="S05院长房间" type="Node2D"] [node name="S05院长房间" type="Node2D"]
[node name="Ground" parent="." instance=ExtResource("1_ff4yb")] [node name="Ground" parent="." instance=ExtResource("1_ff4yb")]
position = Vector2(1, 0)
[node name="AnimationPlayer" parent="Ground" index="0"] [node name="AnimationPlayer" parent="Ground" index="0"]
libraries = {
"": SubResource("AnimationLibrary_ifimj")
}
script = ExtResource("2_j5oim") script = ExtResource("2_j5oim")
oneshot_animation = "" oneshot_animation = ""
[node name="BGSprite2D" parent="Ground" index="2"] [node name="BGSprite2D" parent="Ground" index="2"]
position = Vector2(23, -118) position = Vector2(23, -115)
scale = Vector2(0.333, 0.333) scale = Vector2(0.333, 0.333)
texture = ExtResource("3_3r1q2") texture = ExtResource("3_3r1q2")
[node name="portal_left" parent="Ground/DeployLayer" index="0"]
position = Vector2(26, 1)
[node name="portal_right" parent="Ground/DeployLayer" index="1"] [node name="portal_right" parent="Ground/DeployLayer" index="1"]
position = Vector2(502, 9) position = Vector2(502, 11)
texture = ExtResource("4_gdhoy") texture = ExtResource("4_gdhoy")
target_scene = "c01_s05" target_scene = "c01_s05"
target_portal = "left" target_portal = "left"
@ -58,22 +247,22 @@ default_texture = ExtResource("4_gdhoy")
opened_texture = ExtResource("5_cddn7") opened_texture = ExtResource("5_cddn7")
[node name="座钟" parent="Ground/DeployLayer" index="2" instance=ExtResource("6_v72k7")] [node name="座钟" parent="Ground/DeployLayer" index="2" instance=ExtResource("6_v72k7")]
position = Vector2(334, 16) position = Vector2(334, 18)
texture = ExtResource("7_3tetc") texture = ExtResource("7_3tetc")
texture_cover = ExtResource("7_3tetc") texture_cover = ExtResource("7_3tetc")
editor_filter = "c01" editor_filter = "c01"
content_key = "c01_院长座钟" content_key = "c01_院长座钟"
[node name="床" parent="Ground/DeployLayer" index="3" instance=ExtResource("6_v72k7")] [node name="床" parent="Ground/DeployLayer" index="3" instance=ExtResource("6_v72k7")]
position = Vector2(84, 45) position = Vector2(84, 47)
texture = ExtResource("7_xakd0") texture = ExtResource("7_xakd0")
[node name="钢琴" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_v72k7")] [node name="钢琴" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_v72k7")]
position = Vector2(413, 47) position = Vector2(413, 49)
texture = ExtResource("8_mnduo") texture = ExtResource("8_mnduo")
[node name="桌椅" parent="Ground/DeployLayer" index="5" instance=ExtResource("10_18v0g")] [node name="桌椅" parent="Ground/DeployLayer" index="5" instance=ExtResource("10_18v0g")]
position = Vector2(154, 42) position = Vector2(154, 44)
texture = ExtResource("9_x837o") texture = ExtResource("9_x837o")
title_filter = "c01" title_filter = "c01"
note_key = "c01_院长书桌" note_key = "c01_院长书桌"
@ -81,12 +270,14 @@ note_key = "c01_院长书桌"
[node name="Sign" parent="Ground/DeployLayer/桌椅" index="1"] [node name="Sign" parent="Ground/DeployLayer/桌椅" index="1"]
offset_top = -21.0 offset_top = -21.0
offset_bottom = 59.0 offset_bottom = 59.0
metadata/_edit_use_anchors_ = true
[node name="CollisionShape2D" parent="Ground/DeployLayer/桌椅/Area2D" index="0"] [node name="CollisionShape2D" parent="Ground/DeployLayer/桌椅/Area2D" index="0"]
shape = SubResource("RectangleShape2D_6i5gw") shape = SubResource("RectangleShape2D_6i5gw")
[node name="画框" parent="Ground/DeployLayer" index="6" instance=ExtResource("10_18v0g")] [node name="画框" parent="Ground/DeployLayer" index="6" instance=ExtResource("10_18v0g")]
position = Vector2(277, -28) position = Vector2(277, -26)
rotation = -0.179769
texture = ExtResource("11_6gq1s") texture = ExtResource("11_6gq1s")
title_filter = "notes" title_filter = "notes"
note_key = "notes_挂画" note_key = "notes_挂画"
@ -96,33 +287,33 @@ offset_left = 3.0
offset_top = -7.0 offset_top = -7.0
offset_right = 86.0 offset_right = 86.0
offset_bottom = 73.0 offset_bottom = 73.0
metadata/_edit_use_anchors_ = true
[node name="CollisionShape2D" parent="Ground/DeployLayer/画框/Area2D" index="0"] [node name="CollisionShape2D" parent="Ground/DeployLayer/画框/Area2D" index="0"]
position = Vector2(11, -1) position = Vector2(11, -1)
shape = SubResource("RectangleShape2D_6bim4") shape = SubResource("RectangleShape2D_6bim4")
[node name="鸡毛掸子" parent="Ground/DeployLayer" index="7" instance=ExtResource("10_18v0g")] [node name="ambush鸡毛掸子" parent="Ground/DeployLayer" index="7" instance=ExtResource("15_1uixh")]
position = Vector2(269, 20) unique_name_in_owner = true
position = Vector2(270, 23)
texture = ExtResource("12_jtglg") texture = ExtResource("12_jtglg")
title_filter = "c01" trigger_mode = "interact"
note_key = "c01_鸡毛掸子" one_shot = false
hook_animation = "使用鸡毛掸子"
[node name="Area2D" parent="Ground/DeployLayer/鸡毛掸子" index="3"] [node name="使用鸡毛掸子" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="8"]
position = Vector2(-7, 0) visible = false
position = Vector2(261, 42)
sprite_frames = ExtResource("14_e1bmq")
animation = &"c01_小小蝶_拿鸡毛掸子"
[node name="CollisionShape2D" parent="Ground/DeployLayer/鸡毛掸子/Area2D" index="0"] [node name="Interactable" parent="Ground/DeployLayer" index="9" instance=ExtResource("14_lq1ou")]
shape = SubResource("RectangleShape2D_dq2na") position = Vector2(207, 32)
[node name="Interactable" parent="Ground/DeployLayer" index="8" instance=ExtResource("14_lq1ou")]
position = Vector2(207, 30)
one_shot = false one_shot = false
prop_key = "prop_1012钥匙" prop_key = "prop_1012钥匙"
[node name="CollisionShape2D" parent="Ground/DeployLayer/Interactable/Area2D" index="0"] [node name="CollisionShape2D" parent="Ground/DeployLayer/Interactable/Area2D" index="0"]
shape = SubResource("RectangleShape2D_40ng7") shape = SubResource("RectangleShape2D_5s1ih")
[node name="Ambush" parent="Ground/DeployLayer" index="9" instance=ExtResource("15_1uixh")]
position = Vector2(113, 46)
[node name="PointLight墙" type="PointLight2D" parent="Ground/AmbientLayer" index="0"] [node name="PointLight墙" type="PointLight2D" parent="Ground/AmbientLayer" index="0"]
visible = false visible = false
@ -137,6 +328,7 @@ texture_scale = 0.33
height = 50.0 height = 50.0
[node name="MainPlayer" parent="Ground" index="5"] [node name="MainPlayer" parent="Ground" index="5"]
position = Vector2(261, 40)
character = "小小蝶" character = "小小蝶"
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
@ -161,6 +353,5 @@ texture = ExtResource("3_7u4bh")
[editable path="Ground"] [editable path="Ground"]
[editable path="Ground/DeployLayer/桌椅"] [editable path="Ground/DeployLayer/桌椅"]
[editable path="Ground/DeployLayer/画框"] [editable path="Ground/DeployLayer/画框"]
[editable path="Ground/DeployLayer/鸡毛掸子"]
[editable path="Ground/DeployLayer/Interactable"] [editable path="Ground/DeployLayer/Interactable"]
[editable path="Ground/DeployLayer/Interactable/Sign"] [editable path="Ground/DeployLayer/Interactable/Sign"]

View File

@ -15,6 +15,8 @@ func _ready() -> void:
elif GlobalConfig.DEBUG: elif GlobalConfig.DEBUG:
print("_give_letter 已发放") print("_give_letter 已发放")
func _on_deploy_layer_ready() -> void:
pass
func _give_letter() -> void: func _give_letter() -> void:
set_data("received_letter", true) set_data("received_letter", true)

View File

@ -27,22 +27,18 @@ target_portal = "left"
[node name="Note" parent="Ground/DeployLayer" index="2" instance=ExtResource("3_6lnxd")] [node name="Note" parent="Ground/DeployLayer" index="2" instance=ExtResource("3_6lnxd")]
position = Vector2(250, -22) position = Vector2(250, -22)
note_key = "c02_寻人启事" mode = null
[node name="Note门口" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_6lnxd")] [node name="Note门口" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_6lnxd")]
position = Vector2(311, -27) position = Vector2(311, -27)
mode = "ballon" mode = "ballon"
dialogue = "c02" dialogue = "c02"
note_key = "c02_s01_门口"
[node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_vgxa0")] [node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_vgxa0")]
position = Vector2(135, 56) position = Vector2(135, 56)
lock_player_on_playing_dialogue = null
hook_dialogue_res = null
hook_animation = null
[node name="MainPlayer" parent="Ground" index="5"] [node name="MainPlayer" parent="Ground" index="5"]
position = Vector2(78, 45) position = Vector2(78, 40)
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
texture = null texture = null

View File

@ -1,6 +1,8 @@
@tool @tool
extends AnimationRoot extends AnimationRoot
@onready var wind_blows = $"../DeployLayer/WindBlows" as AnimatedSprite2D
# 覆盖该方法 # 覆盖该方法
func _default_data() -> Dictionary: func _default_data() -> Dictionary:
@ -11,8 +13,20 @@ func _ready() -> void:
super._ready() super._ready()
func _on_deploy_layer_ready() -> void:
pass
func _oneshot_wind(): func _oneshot_wind():
SceneManager.freeze_player(0, "c02_吕萍_风吹过", false, Vector2(200, 0)) SceneManager.freeze_player(0)
%MainPlayer.visible = false
wind_blows.visible = true
wind_blows.play()
wind_blows.animation_finished.connect(_on_wind_finished, CONNECT_ONE_SHOT)
func _on_wind_finished():
%MainPlayer.visible = true
wind_blows.visible = false
func _oneshot_dialog(): func _oneshot_dialog():

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=12 format=3 uid="uid://brck77w81fhvc"] [gd_scene load_steps=13 format=3 uid="uid://brck77w81fhvc"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_wrr6r"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_wrr6r"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s02_animation.gd" id="2_5p8ev"] [ext_resource type="Script" path="res://scene/ground/scene/c02/s02_animation.gd" id="2_5p8ev"]
[ext_resource type="Texture2D" uid="uid://c4647gof464ws" path="res://asset/art/scene/c02/s02_走道/bg_过道.png" id="2_cn1s8"] [ext_resource type="Texture2D" uid="uid://c4647gof464ws" path="res://asset/art/scene/c02/s02_走道/bg_过道.png" id="2_cn1s8"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_fy0o1"] [ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_fy0o1"]
[ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="4_wbif8"]
[ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/old/inspectable.tscn" id="5_nhtbp"] [ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/old/inspectable.tscn" id="5_nhtbp"]
[ext_resource type="Texture2D" uid="uid://ds4yw1wqelhm1" path="res://asset/art/scene/c02/s02_走道/ux_进门鼠疫海报yz.png" id="7_wdwbi"] [ext_resource type="Texture2D" uid="uid://ds4yw1wqelhm1" path="res://asset/art/scene/c02/s02_走道/ux_进门鼠疫海报yz.png" id="7_wdwbi"]
[ext_resource type="Texture2D" uid="uid://dd0sn5e4hwq5m" path="res://asset/art/scene/c02/s02_走道/e_纸人.png" id="7_xsghn"] [ext_resource type="Texture2D" uid="uid://dd0sn5e4hwq5m" path="res://asset/art/scene/c02/s02_走道/e_纸人.png" id="7_xsghn"]
@ -58,16 +59,25 @@ position = Vector2(678, 6)
target_scene = "c02_s03" target_scene = "c02_s03"
target_portal = "left" target_portal = "left"
[node name="几张卫生宣传画" parent="Ground/DeployLayer" index="2" instance=ExtResource("3_fy0o1")] [node name="WindBlows" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="2"]
unique_name_in_owner = true
visible = false
position = Vector2(435, 9)
scale = Vector2(1.2, 1.2)
sprite_frames = ExtResource("4_wbif8")
animation = &"c02_吕萍_风吹过"
[node name="几张卫生宣传画" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_fy0o1")]
position = Vector2(275, -30) position = Vector2(275, -30)
title_filter = "c02"
note_key = "c02_卫生宣传画" note_key = "c02_卫生宣传画"
[node name="鼠疫海报" parent="Ground/DeployLayer" index="3" instance=ExtResource("12_0fckv")] [node name="鼠疫海报" parent="Ground/DeployLayer" index="4" instance=ExtResource("12_0fckv")]
position = Vector2(440, -21) position = Vector2(439, -18)
texture_cover = ExtResource("7_wdwbi") texture_cover = ExtResource("7_wdwbi")
content_key = "c02_鼠疫海报" content_key = "c02_鼠疫海报"
[node name="纸人" parent="Ground/DeployLayer" index="4" instance=ExtResource("5_nhtbp")] [node name="纸人" parent="Ground/DeployLayer" index="5" instance=ExtResource("5_nhtbp")]
position = Vector2(599, 44) position = Vector2(599, 44)
texture = ExtResource("7_xsghn") texture = ExtResource("7_xsghn")
flip_h = true flip_h = true

View File

@ -10,3 +10,6 @@ func _default_data() -> Dictionary:
func _ready() -> void: func _ready() -> void:
super._ready() super._ready()
func _on_deploy_layer_ready() -> void:
pass

81
scene/index_page.gd Normal file
View File

@ -0,0 +1,81 @@
extends Control
@onready var settings = $Settings
@onready var animation_player = $AnimationPlayer as AnimationPlayer
@onready var animation_root = $AnimationRoot as Control
@onready var sfx = %Sfx as Sfx
@onready var newgame_btn = %NewGame as Button
@onready var resume_btn = %Resume as Button
@onready var quit_btn = %Quit as Button
var main_scene = preload("res://scene/main.tscn")
var animation_finished = false
func _ready():
if GlobalConfig.DEBUG:
print("Index Page Ready")
newgame_btn.pressed.connect(_on_newgame_pressed)
resume_btn.pressed.connect(_on_resume_pressed)
quit_btn.pressed.connect(_on_quit_pressed)
_check_resume_btn()
if SceneManager.first_entered:
SceneManager.first_entered = false
# 播放开始动画
animation_player.play("intro")
animation_player.animation_finished.connect(_on_intro_finished)
else:
animation_finished = true
func _on_intro_finished(_a):
animation_root.visible = false
animation_finished = true
func _check_resume_btn():
if not ArchiveManager.archives.has(1):
resume_btn.queue_free()
func _on_newgame_pressed():
sfx.global_play()
# 覆盖使用 1 号存档
ArchiveManager.create_and_use_new_archive(1)
_enter_main_scene()
func _on_resume_pressed():
sfx.global_play()
# 继续一号存档
if GlobalConfig.DEBUG:
print("Resume")
if ArchiveManager.archives.has(1):
GlobalConfigManager.config.current_selected_archive_id = 1
ArchiveManager.load_archive()
else:
ArchiveManager.create_and_use_new_archive(1)
_enter_main_scene()
func _enter_main_scene():
get_tree().change_scene_to_packed(main_scene)
func _on_quit_pressed():
# 退出时点击音效将无法播放
sfx.global_play()
SceneManager.quit_game()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("escape"):
get_viewport().set_input_as_handled()
if not animation_finished:
# 跳过开始动画
animation_player.stop()
animation_root.visible = false
animation_finished = true
else:
# 设置菜单
settings.visible = true

131
scene/index_page.tscn Normal file
View File

@ -0,0 +1,131 @@
[gd_scene load_steps=11 format=3 uid="uid://c4ycvdsabi7lw"]
[ext_resource type="Script" path="res://scene/index_page.gd" id="1_c7y7r"]
[ext_resource type="Texture2D" uid="uid://5xv603j8tuon" path="res://asset/art/ui/entrance/菜单背景1.png" id="1_jxn4k"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="2_cac5f"]
[ext_resource type="PackedScene" uid="uid://beok2r6fgburn" path="res://scene/settings/settings.tscn" id="4_5m37n"]
[sub_resource type="Animation" id="Animation_8kiap"]
resource_name = "default"
[sub_resource type="AnimationLibrary" id="AnimationLibrary_0d65a"]
_data = {
"intro": SubResource("Animation_8kiap")
}
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_gu56a"]
content_margin_top = 4.0
content_margin_bottom = 4.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q8n5c"]
bg_color = Color(0.327299, 0.327299, 0.327299, 0.619608)
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
expand_margin_top = 4.0
expand_margin_bottom = 4.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_scxsv"]
bg_color = Color(0.811765, 0.811765, 0.811765, 0.521569)
border_color = Color(0.336608, 0.336608, 0.336608, 0.517647)
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
expand_margin_top = 4.0
expand_margin_bottom = 4.0
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_vyh3d"]
content_margin_top = 4.0
content_margin_bottom = 4.0
[node name="IndexPage" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_c7y7r")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_0d65a")
}
[node name="AnimationRoot" type="Control" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Sfx" parent="." instance=ExtResource("2_cac5f")]
unique_name_in_owner = true
[node name="TextureRect" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("1_jxn4k")
expand_mode = 1
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = 137.0
offset_top = -39.0
offset_right = 225.0
offset_bottom = 80.0
grow_horizontal = 2
grow_vertical = 2
[node name="NewGame" type="Button" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_gu56a")
theme_override_styles/hover = SubResource("StyleBoxFlat_q8n5c")
theme_override_styles/pressed = SubResource("StyleBoxFlat_scxsv")
theme_override_styles/normal = SubResource("StyleBoxEmpty_vyh3d")
text = "index_新游戏"
[node name="Resume" type="Button" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_gu56a")
theme_override_styles/hover = SubResource("StyleBoxFlat_q8n5c")
theme_override_styles/pressed = SubResource("StyleBoxFlat_scxsv")
theme_override_styles/normal = SubResource("StyleBoxEmpty_vyh3d")
text = "index_继续游戏"
[node name="Quit" type="Button" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_gu56a")
theme_override_styles/hover = SubResource("StyleBoxFlat_q8n5c")
theme_override_styles/pressed = SubResource("StyleBoxFlat_scxsv")
theme_override_styles/normal = SubResource("StyleBoxEmpty_vyh3d")
text = "index_退出游戏"
[node name="Settings" parent="." instance=ExtResource("4_5m37n")]
visible = false
[node name="ColorRect" type="ColorRect" parent="Settings"]
z_index = -1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0, 0, 0, 0.862745)

View File

@ -5,12 +5,25 @@ extends Node2D
TranslationServer.set_locale(val) TranslationServer.set_locale(val)
locale = val locale = val
@onready var settings = %Settings
func _ready() -> void: func _ready() -> void:
if GlobalConfig.DEBUG: %UILayer.layer = GlobalConfig.CANVAS_LAYER_UI
get_window().always_on_top = true
$UILayer.layer = GlobalConfig.CANVAS_LAYER_UI
%ColorRectTop.visible = true %ColorRectTop.visible = true
%ColorRectBottom.visible = true %ColorRectBottom.visible = true
# focus_mode = Control.FOCUS_CLICK
# settings.exited.connect(grab_focus)
func _on_settings_hide():
SceneManager.release_player()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("escape"):
settings.visible = true
get_viewport().set_input_as_handled()
elif event.is_action_pressed("bag"):
SceneManager.show_bag()
get_viewport().set_input_as_handled()

View File

@ -1,24 +1,23 @@
[gd_scene load_steps=9 format=3 uid="uid://dygvcmykn02n8"] [gd_scene load_steps=10 format=3 uid="uid://dygvcmykn02n8"]
[ext_resource type="Script" path="res://scene/main.gd" id="1_pks84"] [ext_resource type="Script" path="res://scene/main.gd" id="1_pks84"]
[ext_resource type="PackedScene" uid="uid://3gk1gxwanw24" path="res://scene/shading/shading_layer.tscn" id="2_d1re1"] [ext_resource type="PackedScene" uid="uid://3gk1gxwanw24" path="res://scene/shading/shading_layer.tscn" id="2_d1re1"]
[ext_resource type="PackedScene" uid="uid://dc778gsjfr3ky" path="res://scene/hud/prop_hud.tscn" id="4_t7gb2"] [ext_resource type="PackedScene" uid="uid://dc778gsjfr3ky" path="res://scene/prop/prop_hud.tscn" id="4_t7gb2"]
[ext_resource type="PackedScene" uid="uid://5g07x6q7wwr1" path="res://scene/notification/notification.tscn" id="5_3gg5t"] [ext_resource type="PackedScene" uid="uid://5g07x6q7wwr1" path="res://scene/notification/notification.tscn" id="5_3gg5t"]
[ext_resource type="PackedScene" uid="uid://cekhj65axie0p" path="res://scene/popup/prop_inspector.tscn" id="5_ux0rw"] [ext_resource type="PackedScene" uid="uid://cekhj65axie0p" path="res://scene/prop/prop_inspector.tscn" id="5_ux0rw"]
[ext_resource type="Environment" uid="uid://c6ri8tn5qt6fe" path="res://scene/ground/environment.tres" id="9_jsof5"] [ext_resource type="Environment" uid="uid://c6ri8tn5qt6fe" path="res://scene/ground/environment.tres" id="9_jsof5"]
[ext_resource type="PackedScene" uid="uid://beok2r6fgburn" path="res://scene/settings/settings.tscn" id="9_muu0b"]
[ext_resource type="PackedScene" uid="uid://clxgkj80yin2" path="res://scene/ground/ground_loader.tscn" id="10_8rc5n"] [ext_resource type="PackedScene" uid="uid://clxgkj80yin2" path="res://scene/ground/ground_loader.tscn" id="10_8rc5n"]
[ext_resource type="PackedScene" uid="uid://cvbt5qm70cg7t" path="res://scene/journal/journal.tscn" id="10_durpa"] [ext_resource type="PackedScene" uid="uid://cvbt5qm70cg7t" path="res://scene/journal/journal.tscn" id="10_durpa"]
[node name="Main" type="Node2D"] [node name="Main" type="Node2D"]
script = ExtResource("1_pks84") script = ExtResource("1_pks84")
locale = "en"
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = ExtResource("9_jsof5") environment = ExtResource("9_jsof5")
[node name="GroundLoader" parent="." instance=ExtResource("10_8rc5n")] [node name="GroundLoader" parent="." instance=ExtResource("10_8rc5n")]
position = Vector2(1, 0) position = Vector2(1, 0)
ignore_archive = true
current_scene = "c01_s05" current_scene = "c01_s05"
entrance_portal = "right" entrance_portal = "right"
@ -26,8 +25,10 @@ entrance_portal = "right"
[node name="PropInspector" parent="." instance=ExtResource("5_ux0rw")] [node name="PropInspector" parent="." instance=ExtResource("5_ux0rw")]
unique_name_in_owner = true unique_name_in_owner = true
layer = 21
[node name="UILayer" type="CanvasLayer" parent="."] [node name="UILayer" type="CanvasLayer" parent="."]
unique_name_in_owner = true
layer = 12 layer = 12
[node name="ColorRectTop" type="ColorRect" parent="UILayer"] [node name="ColorRectTop" type="ColorRect" parent="UILayer"]
@ -76,3 +77,7 @@ metadata/_edit_use_anchors_ = true
[node name="Journal" parent="." instance=ExtResource("10_durpa")] [node name="Journal" parent="." instance=ExtResource("10_durpa")]
visible = false visible = false
[node name="Settings" parent="." instance=ExtResource("9_muu0b")]
unique_name_in_owner = true
visible = false

View File

@ -9,16 +9,25 @@ class_name MainPlayer
current_animation_config = PlayerAnimationConfig.ANIMATION_CONFIG[val] current_animation_config = PlayerAnimationConfig.ANIMATION_CONFIG[val]
current_status = PlayerAnimationConfig.MOVEMENT_IDLE current_status = PlayerAnimationConfig.MOVEMENT_IDLE
if is_node_ready(): if is_node_ready():
var _scale = current_animation_config["scale"] sprite.scale = current_animation_config["scale"]
sprite.scale = Vector2(_scale, _scale)
# @export var shadow_color := Color(0.1, 0.1, 0.1, 0.7) # @export var shadow_color := Color(0.1, 0.1, 0.1, 0.7)
# var shadow_y := 0.0 # var shadow_y := 0.0
@export var player_movement_rect := Rect2(50, -500, 1400, 1000) @export var player_movement_rect := Rect2(50, -500, 1400, 1000)
@export var velocity_ratio := 1.0 @export var velocity_ratio := 1.0
# action_locked 用于设置界面等强制锁定action_freezed 用于查看物品等锁定
# action_locked 优先级高于 action_freezed
# action_locked 对应 lock 与 unlock 方法
@export var action_locked := false: @export var action_locked := false:
set(val): set(val):
action_locked = val action_locked = val
_process_action_lock() _process_action_lock()
# action_freezed 对应 freeze 与 release 方法
@export var action_freezed := false:
set(val):
action_freezed = val
_process_action_lock()
@export_enum("idle", "walking", "running") var current_status := 0: @export_enum("idle", "walking", "running") var current_status := 0:
set(val): set(val):
current_status = val current_status = val
@ -42,12 +51,13 @@ var current_animation_config := PlayerAnimationConfig.ANIMATION_CONFIG[character
func _ready() -> void: func _ready() -> void:
os_contaner.modulate.a = 0.0 os_contaner.modulate.a = 0.0
# set up animated sprite # set up animated sprite
var _scale = current_animation_config["scale"] sprite.scale = current_animation_config["scale"]
sprite.scale = Vector2(_scale, _scale)
_play_animation() _play_animation()
if Engine.is_editor_hint():
return
footstep_timer.timeout.connect(_on_footstep_timer_timeout) footstep_timer.timeout.connect(_on_footstep_timer_timeout)
footstep_timer.stop() footstep_timer.stop()
SceneManager.focus_player(self) # SceneManager.focus_player(self)
func _on_footstep_timer_timeout(): func _on_footstep_timer_timeout():
@ -59,7 +69,7 @@ func _on_footstep_timer_timeout():
func _process_action_lock() -> void: func _process_action_lock() -> void:
# reset status to idle or stay # reset status to idle or stay
if action_locked: if action_locked or action_freezed:
velocity = Vector2.ZERO velocity = Vector2.ZERO
if ( if (
current_status == PlayerAnimationConfig.MOVEMENT_WALKING current_status == PlayerAnimationConfig.MOVEMENT_WALKING
@ -94,6 +104,7 @@ func _play_animation() -> void:
if not sprite: if not sprite:
return return
sprite.offset = current_animation_config["foot_offset"] sprite.offset = current_animation_config["foot_offset"]
sprite.scale = current_animation_config["scale"]
# reset the os label position on animation changed. # reset the os label position on animation changed.
_reset_os_and_shadow_position() _reset_os_and_shadow_position()
var config = current_animation_config[current_status] var config = current_animation_config[current_status]
@ -135,7 +146,7 @@ func _get_speed(direction: Vector2) -> Vector2:
func _physics_process(_delta: float) -> void: func _physics_process(_delta: float) -> void:
if action_locked or Engine.is_editor_hint(): if action_locked or action_freezed or Engine.is_editor_hint():
velocity = Vector2.ZERO velocity = Vector2.ZERO
return return
var x_direction := Input.get_axis("left", "right") var x_direction := Input.get_axis("left", "right")
@ -157,7 +168,7 @@ func _physics_process(_delta: float) -> void:
# drag the camera marker against the player movement # drag the camera marker against the player movement
# so there will be a better vision in front of the player. # so there will be a better vision in front of the player.
func _tweak_camera_marker(): func _tweak_camera_marker():
CameraFocusMarker.tweak_position(velocity, facing_direction) SceneManager.get_camera_marker().tweak_position(velocity, facing_direction)
var lock_mutex = Mutex.new() var lock_mutex = Mutex.new()
@ -165,15 +176,41 @@ var release_timer: SceneTreeTimer
# lock_time: the time to lock the player action. 0 means lock forever, thus the player will be locked until release_player is called. # lock_time: the time to lock the player action. 0 means lock forever, thus the player will be locked until release_player is called.
func freeze_player(lock_time: float, animation: String, loop: bool, offset: Vector2) -> void: func freeze_player(lock_time: float, action_animation: int, auto_quit: bool) -> void:
lock_mutex.lock() lock_mutex.lock()
if not action_locked: if not action_freezed:
action_locked = true action_freezed = true
if current_animation_config.has(action_animation):
# animation_name, scale, offset
var config = current_animation_config[action_animation]
var animation = config[0]
if not animation and config.size() >= 4:
animation = config[4] if facing_direction.x > 0.0 else config[3]
sprite.scale = config[1] if config.size() > 1 else Vector2.ONE
sprite.offset = config[2] if config.size() > 2 else Vector2.ZERO
if animation and sprite.sprite_frames.has_animation(animation):
sprite.sprite_frames.set_animation_loop(animation, false)
sprite.play(animation)
if auto_quit:
# reset animation after one play
sprite.animation_finished.connect(_play_animation, CONNECT_ONE_SHOT)
if lock_time:
if release_timer and release_timer.time_left > 0:
release_timer.time_left = max(lock_time, release_timer.time_left)
else:
release_timer = get_tree().create_timer(lock_time)
release_timer.timeout.connect(release_player)
lock_mutex.unlock()
func freeze_and_play(lock_time: float, animation: String, auto_quit: bool) -> void:
lock_mutex.lock()
if not action_freezed:
action_freezed = true
if animation and sprite.sprite_frames.has_animation(animation): if animation and sprite.sprite_frames.has_animation(animation):
sprite.sprite_frames.set_animation_loop(animation, loop) sprite.sprite_frames.set_animation_loop(animation, false)
sprite.offset = offset
sprite.play(animation) sprite.play(animation)
if not loop: if auto_quit:
# reset animation after one play # reset animation after one play
sprite.animation_finished.connect(_play_animation, CONNECT_ONE_SHOT) sprite.animation_finished.connect(_play_animation, CONNECT_ONE_SHOT)
if lock_time: if lock_time:
@ -188,10 +225,10 @@ func freeze_player(lock_time: float, animation: String, loop: bool, offset: Vect
func release_player(): func release_player():
release_timer = null release_timer = null
lock_mutex.lock() lock_mutex.lock()
action_locked = false action_freezed = false
# velocity_ratio = 1.0 # velocity_ratio = 1.0
lock_mutex.unlock() lock_mutex.unlock()
_play_animation() # _play_animation()
# func _draw() -> void: # func _draw() -> void:
@ -271,3 +308,19 @@ func pop_os(lines := []):
func _os_load_line(line): func _os_load_line(line):
os_label.dialogue_line = line os_label.dialogue_line = line
# func walk_to(pos: Vector2, duration: float, auto_unfreeze := true) -> void:
# var tween = create_tween()
# action_freezed = true
# velocity = Vector2.ZERO
# current_status = PlayerAnimationConfig.MOVEMENT_WALKING
# facing_direction.x = 1.0 if pos.x > global_position.x else -1.0
# _play_animation()
# tween.tween_property(self, "global_position", pos, duration)
# if auto_unfreeze:
# tween.tween_callback(_after_walk_to)
# func _after_walk_to():
# action_freezed = false

View File

@ -1,8 +1,7 @@
[gd_scene load_steps=9 format=3 uid="uid://cjhw5ecygrqty"] [gd_scene load_steps=8 format=3 uid="uid://cjhw5ecygrqty"]
[ext_resource type="Script" path="res://scene/player/main_player.gd" id="1_3a78y"] [ext_resource type="Script" path="res://scene/player/main_player.gd" id="1_3a78y"]
[ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="2_3w63u"] [ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="2_3w63u"]
[ext_resource type="Texture2D" uid="uid://may55b2uerbw" path="res://asset/art/neutral_point_light.png" id="3_h4uja"]
[ext_resource type="Texture2D" uid="uid://bucpmiscjaem0" path="res://asset/art/ui/对话框.png" id="4_0qo0c"] [ext_resource type="Texture2D" uid="uid://bucpmiscjaem0" path="res://asset/art/ui/对话框.png" id="4_0qo0c"]
[ext_resource type="FontFile" uid="uid://coy0c115cjmv5" path="res://asset/font/MPLUS中文像素.TTF" id="4_4jk1c"] [ext_resource type="FontFile" uid="uid://coy0c115cjmv5" path="res://asset/font/MPLUS中文像素.TTF" id="4_4jk1c"]
[ext_resource type="Script" path="res://addons/dialogue_manager/dialogue_label.gd" id="5_tclgd"] [ext_resource type="Script" path="res://addons/dialogue_manager/dialogue_label.gd" id="5_tclgd"]
@ -37,20 +36,12 @@ wait_time = 0.5
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_fno82") shape = SubResource("RectangleShape2D_fno82")
[node name="PointLight2D" type="PointLight2D" parent="."]
position = Vector2(1, -44)
scale = Vector2(0.810547, 0.849609)
energy = 0.2
texture = ExtResource("3_h4uja")
texture_scale = 2.0
height = 20.0
[node name="OSPivot" type="Control" parent="."] [node name="OSPivot" type="Control" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 3 layout_mode = 3
anchors_preset = 0 anchors_preset = 0
offset_top = -50.0 offset_top = -60.0
offset_bottom = -50.0 offset_bottom = -60.0
mouse_filter = 2 mouse_filter = 2
[node name="MarginContainer" type="MarginContainer" parent="OSPivot"] [node name="MarginContainer" type="MarginContainer" parent="OSPivot"]

View File

@ -1,15 +1,19 @@
class_name PlayerAnimationConfig extends Object class_name PlayerAnimationConfig extends RefCounted
enum { enum {
# movement animation
MOVEMENT_IDLE, MOVEMENT_IDLE,
MOVEMENT_WALKING, MOVEMENT_WALKING,
MOVEMENT_RUNNING, MOVEMENT_RUNNING,
# action animation
ACTION_NONE,
ACTION_LOOKUP_WALL,
} }
const ANIMATION_CONFIG = { const ANIMATION_CONFIG = {
"吕萍": "吕萍":
{ {
"scale": 0.6, "scale": Vector2(0.6, 0.6),
"speed_walking": 75.0, "speed_walking": 75.0,
"running_locked": false, "running_locked": false,
"speed_runnig": 120.0, "speed_runnig": 120.0,
@ -22,16 +26,18 @@ const ANIMATION_CONFIG = {
MOVEMENT_IDLE: [&"c00_吕萍_idle_left", &"c00_吕萍_idle_right"], MOVEMENT_IDLE: [&"c00_吕萍_idle_left", &"c00_吕萍_idle_right"],
MOVEMENT_WALKING: [&"c00_吕萍_walking_left", &"c00_吕萍_walking_right"], MOVEMENT_WALKING: [&"c00_吕萍_walking_left", &"c00_吕萍_walking_right"],
MOVEMENT_RUNNING: [&"c00_吕萍_running_left", &"c00_吕萍_running_right"], MOVEMENT_RUNNING: [&"c00_吕萍_running_left", &"c00_吕萍_running_right"],
# animation_name, scale, offset
ACTION_LOOKUP_WALL: [&"c00_吕萍_记笔记_right", Vector2(1.2, 1.2), Vector2(0, 0)],
}, },
"吕萍爬行": "吕萍爬行":
{ {
"scale": 1.0, "scale": Vector2(0.6, 0.6),
"speed_walking": 50.0, "speed_walking": 50.0,
"running_locked": true, "running_locked": true,
"speed_runnig": 50.0, "speed_runnig": 50.0,
"walk_footstep": 0.7, "walk_footstep": 0.7,
"run_footstep": 0.7, "run_footstep": 0.7,
"os_height": 35.0, "os_height": 10.0,
# 人物脚底 offset吕萍为 0高 200px足底在 100px 处 # 人物脚底 offset吕萍为 0高 200px足底在 100px 处
# 吕萍爬行高 59px # 吕萍爬行高 59px
"foot_offset": Vector2(0, 27.0), "foot_offset": Vector2(0, 27.0),
@ -41,7 +47,7 @@ const ANIMATION_CONFIG = {
}, },
"吕萍带小猫": "吕萍带小猫":
{ {
"scale": 0.6, "scale": Vector2(0.6, 0.6),
"speed_walking": 75.0, "speed_walking": 75.0,
"running_locked": true, "running_locked": true,
"speed_runnig": 75.0, "speed_runnig": 75.0,
@ -56,7 +62,7 @@ const ANIMATION_CONFIG = {
}, },
"小蝶": "小蝶":
{ {
"scale": 0.6, "scale": Vector2.ONE,
"speed_walking": 75.0, "speed_walking": 75.0,
"running_locked": true, "running_locked": true,
"speed_runnig": 75.0, "speed_runnig": 75.0,
@ -71,20 +77,22 @@ const ANIMATION_CONFIG = {
}, },
"小小蝶": "小小蝶":
{ {
"scale": 1.0, "scale": Vector2.ONE,
"speed_walking": 65.0, "speed_walking": 65.0,
"running_locked": false, "running_locked": false,
"speed_runnig": 100.0, "speed_runnig": 100.0,
"walk_footstep": 0.5, "walk_footstep": 0.5,
"run_footstep": 7.0 / 10.0 / 2.0, "run_footstep": 7.0 / 10.0 / 2.0,
"os_height": 30.0, "os_height": 10.0,
# 人物脚底 offset吕萍为 0高 200px足底在 100px 处 # 人物脚底 offset吕萍为 0高 200px足底在 100px 处
# 小蝶高 124px行走时 116px # 小蝶高 124px行走时 116px
"foot_offset": Vector2(0, 20.0), "foot_offset": Vector2(0, 20.0),
MOVEMENT_IDLE: [&"c01_小小蝶_idle_l", &"c01_小小蝶_idle_r"], MOVEMENT_IDLE: [&"c01_小小蝶_idle_l", &"c01_小小蝶_idle_r"],
# 此处为[2][3]分别为 sprite 向左、向右时的 offset # 此处为[2][3]分别为 sprite 向左、向右时的 offset
MOVEMENT_WALKING: MOVEMENT_WALKING:
[&"c01_小小蝶_walking_l", &"c01_小小蝶_walking_r", Vector2(0, 4.0), Vector2(0, 4.0)], [&"c01_小小蝶_walking_l", &"c01_小小蝶_walking_r"],
MOVEMENT_RUNNING: [&"c01_小小蝶_running_l", &"c01_小小蝶_running_r"], MOVEMENT_RUNNING: [&"c01_小小蝶_running_l", &"c01_小小蝶_running_r"],
# animation_name, scale, offset, left, right
ACTION_LOOKUP_WALL: [&"", Vector2(1, 1), Vector2(0, 20.0), &"c01_小小蝶_抬头_l", &"c01_小小蝶_抬头_r"],
}, },
} }

5
scene/prop/prop_bag.gd Normal file
View File

@ -0,0 +1,5 @@
extends CanvasLayer
func _ready():
layer = GlobalConfig.CANVAS_LAYER_BAG

109
scene/prop/prop_bag.tscn Normal file
View File

@ -0,0 +1,109 @@
[gd_scene load_steps=3 format=3 uid="uid://b6gbolo1o7wdf"]
[ext_resource type="Script" path="res://scene/prop/prop_bag.gd" id="1_f3hpu"]
[ext_resource type="Texture2D" uid="uid://byhsxyikuvcfn" path="res://asset/art/ui/小蝶笔记.png" id="2_3s314"]
[node name="PropBag" type="CanvasLayer"]
script = ExtResource("1_f3hpu")
[node name="Control" type="Control" parent="."]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="TextureRect" type="TextureRect" parent="Control"]
layout_mode = 1
anchors_preset = 14
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_top = -120.0
offset_bottom = 120.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("2_3s314")
expand_mode = 5
stretch_mode = 2
[node name="GridContainer" type="GridContainer" parent="Control"]
custom_minimum_size = Vector2(270, 120)
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -20.0
offset_right = 20.0
offset_bottom = 20.0
grow_horizontal = 2
grow_vertical = 2
columns = 9
[node name="Panel" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel2" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel3" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel4" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel5" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel6" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel7" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel8" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel9" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel10" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel11" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel12" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel13" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel14" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel15" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
[node name="Panel16" type="Panel" parent="Control/GridContainer"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

Some files were not shown because too many files have changed in this diff Show More