实现完整的道具交互 UX 效果

This commit is contained in:
cakipaul 2025-01-13 16:09:57 +08:00
parent 88eede1301
commit adab1e536d
57 changed files with 1117 additions and 1038 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,16 +1,34 @@
keys,zh_Hans,en,_character,_notes,_tags keys,zh_Hans,en,_character,_notes,_tags
c01_纸包钥匙,一张纸条包着钥匙,,,, c01_纸包钥匙,一张纸条包着钥匙,,,,
c02_寻人启事1,似乎是一张寻人启事,,,,
c02_寻人启事2,脸的部分被撕掉了,看不清,,,,
=>en,=>en,,,,
c01_获得令牌,令牌,,获得,,[#item]
c01_获得灵魂令牌,带有灵魂的令牌,,获得,,[#item]
c01_获得院长信件,院长的信件,,获得,,[#item]
c02_获得1012钥匙,1012钥匙,,获得,,[#item]
c02_获得老虎钳,老虎钳,,获得,,[#item]
c02_获得绳子,绳子,,获得,,[#item]
c02_获得小猫玩具脑袋,小猫玩具脑袋,,获得,,[#item]
c02_获得小猫玩具,小猫玩具,,获得,,[#item]
c02_获得钥匙,钥匙,,获得,,[#item]
c02_获得火柴,火柴,,获得,,[#item]
c02_1014钥匙,1014钥匙,,获得,,[#item]
c02_老鼠洞1,一个老鼠洞,,,,
c02_老鼠洞2,在这种楼里挺常见的,,,,
ui_获得,获得,,,,
ui_退出,退出,Exit,,, ui_退出,退出,Exit,,,
ui_阅读,阅读,Read,,, ui_阅读,阅读,Read,,,
ui_收起,收起,Hold,,, ui_收起,收起,Hold,,,
prop_令牌,令牌,,,,[#texture=c01/令牌物品.png] prop_空手,空手,,,,
prop_装有灵魂的令牌,装有灵魂的令牌,,,,[#texture=c01/装有灵魂的令牌物品.png] prop_令牌,令牌,,,,[#texture=c01/令牌物品.png][#inspect=c01/令牌.png]
prop_小猫玩具的脑袋,小猫玩具的脑袋,Catty's Head,,,[#texture=c02/小猫玩具脑袋物品.png] prop_装有灵魂的令牌,装有灵魂的令牌,,,,[#texture=c01/装有灵魂的令牌物品.png][#inspect=c01/装有灵魂的令牌.png]
prop_绳子,绳子,Rope,,,[#texture=c02/绳子物品.png] prop_小猫玩具的脑袋,小猫玩具的脑袋,Catty's Head,,,[#texture=c02/小猫玩具脑袋物品.png][#inspect=c02/小猫玩具脑袋.png]
prop_1012钥匙,1012钥匙,1012 Key,,,[#texture=c02/1012钥匙物品.png] prop_绳子,绳子,Rope,,,[#texture=c02/绳子物品.png][#inspect=c02/绳子.png]
prop_老虎钳,老虎钳,,,,[#texture=c02/老虎钳物品.png] prop_1012钥匙,1012钥匙,1012 Key,,,[#texture=c02/1012钥匙物品.png][#inspect=c02/1012钥匙.png]
prop_3014旋转锁钥匙,3014旋转锁钥匙,,,,[#texture=c02/3014旋转锁钥匙物品.png] prop_老虎钳,老虎钳,,,,[#texture=c02/老虎钳物品.png][#inspect=c02/老虎钳.png]
prop_小猫玩具完整,小猫玩具,,,,[#texture=c02/小猫玩具完整物品.png] prop_3014旋转锁钥匙,3014旋转锁钥匙,,,,[#texture=c02/3014旋转锁钥匙物品.png][#inspect=c02/3014旋转锁钥匙.png]
prop_小猫玩具完整,小猫玩具,,,,[#texture=c02/小猫玩具完整物品.png][#inspect=c02/小猫玩具完整.png]
notes_纸条,纸条,,,, notes_纸条,纸条,,,,
notes_锁住了,锁住了,,,, notes_锁住了,锁住了,,,,
notes_打不开,打不开,,,, notes_打不开,打不开,,,,
@ -24,12 +42,12 @@ c01_鸡毛掸子,这是鸡毛掸子吗?,,,,
c01_院长书桌,书桌上好像有本书,,,, c01_院长书桌,书桌上好像有本书,,,,
c01_院长座钟,唔...下午一点了,,,, c01_院长座钟,唔...下午一点了,,,,
c02_绳子剪刀,绳子和剪刀,,,, c02_绳子剪刀,绳子和剪刀,,,,
c02_寻人启事1,似乎是一张寻人启事,,,, c02_寻人启事,"似乎是一张寻人启事
c02_寻人启事2,脸的部分被撕掉了,看不清,,,, 脸的部分被撕掉了,看不清",,,,
c02_玩具缺脑袋,这个玩具缺了个脑袋,,,, c02_玩具缺脑袋,这个玩具缺了个脑袋,,,,
c02_卫生宣传画,几张卫生宣传画,,,, c02_卫生宣传画,几张卫生宣传画,,,,
c02_老鼠洞1,一个老鼠洞,,,, c02_老鼠洞,"一个老鼠洞
c02_老鼠洞2,在这种楼里挺常见的,,,, 在这种楼里挺常见的",,,,
c02_十几年前的报纸,十几年前的报纸,,,, c02_十几年前的报纸,十几年前的报纸,,,,
c02_又是寻人启示,又是那张寻人启示,,,, c02_又是寻人启示,又是那张寻人启示,,,,
c02_墙上的海报被撕掉了,墙上的海报被撕掉了,,,, c02_墙上的海报被撕掉了,墙上的海报被撕掉了,,,,
@ -63,17 +81,5 @@ c02_锁开了,锁开了,,,,
c02_口袋里有东西,口袋里有东西,,,, c02_口袋里有东西,口袋里有东西,,,,
c02_雾太大,雾太大了,看不清路,,,, c02_雾太大,雾太大了,看不清路,,,,
c02_八音盒,是个八音盒,,,, c02_八音盒,是个八音盒,,,,
=>en,=>en,,,,
c02_祝女儿早日康复,祝女儿早日康复,,,, c02_祝女儿早日康复,祝女儿早日康复,,,,
c02_图案一样,这图案和我手臂上的一摸一样,,,, c02_图案一样,这图案和我手臂上的一摸一样,,,,
c01_获得令牌,令牌,,获得,,[#item]
c01_获得灵魂令牌,带有灵魂的令牌,,获得,,[#item]
c01_获得院长信件,院长的信件,,获得,,[#item]
c02_获得1012钥匙,1012钥匙,,获得,,[#item]
c02_获得老虎钳,老虎钳,,获得,,[#item]
c02_获得绳子,绳子,,获得,,[#item]
c02_获得小猫玩具脑袋,小猫玩具脑袋,,获得,,[#item]
c02_获得小猫玩具,小猫玩具,,获得,,[#item]
c02_获得钥匙,钥匙,,获得,,[#item]
c02_获得火柴,火柴,,获得,,[#item]
c02_1014钥匙,1014钥匙,,获得,,[#item]

1 keys zh_Hans en _character _notes _tags
2 c01_纸包钥匙 一张纸条包着钥匙
3 c02_寻人启事1 似乎是一张寻人启事
4 c02_寻人启事2 脸的部分被撕掉了,看不清
5 =>en =>en
6 c01_获得令牌 令牌 获得 [#item]
7 c01_获得灵魂令牌 带有灵魂的令牌 获得 [#item]
8 c01_获得院长信件 院长的信件 获得 [#item]
9 c02_获得1012钥匙 1012钥匙 获得 [#item]
10 c02_获得老虎钳 老虎钳 获得 [#item]
11 c02_获得绳子 绳子 获得 [#item]
12 c02_获得小猫玩具脑袋 小猫玩具脑袋 获得 [#item]
13 c02_获得小猫玩具 小猫玩具 获得 [#item]
14 c02_获得钥匙 钥匙 获得 [#item]
15 c02_获得火柴 火柴 获得 [#item]
16 c02_1014钥匙 1014钥匙 获得 [#item]
17 c02_老鼠洞1 一个老鼠洞
18 c02_老鼠洞2 在这种楼里挺常见的
19 ui_获得 获得
20 ui_退出 退出 Exit
21 ui_阅读 阅读 Read
22 ui_收起 收起 Hold
23 prop_令牌 prop_空手 令牌 空手 [#texture=c01/令牌物品.png]
24 prop_装有灵魂的令牌 prop_令牌 装有灵魂的令牌 令牌 [#texture=c01/装有灵魂的令牌物品.png] [#texture=c01/令牌物品.png][#inspect=c01/令牌.png]
25 prop_小猫玩具的脑袋 prop_装有灵魂的令牌 小猫玩具的脑袋 装有灵魂的令牌 Catty's Head [#texture=c02/小猫玩具脑袋物品.png] [#texture=c01/装有灵魂的令牌物品.png][#inspect=c01/装有灵魂的令牌.png]
26 prop_绳子 prop_小猫玩具的脑袋 绳子 小猫玩具的脑袋 Rope Catty's Head [#texture=c02/绳子物品.png] [#texture=c02/小猫玩具脑袋物品.png][#inspect=c02/小猫玩具脑袋.png]
27 prop_1012钥匙 prop_绳子 1012钥匙 绳子 1012 Key Rope [#texture=c02/1012钥匙物品.png] [#texture=c02/绳子物品.png][#inspect=c02/绳子.png]
28 prop_老虎钳 prop_1012钥匙 老虎钳 1012钥匙 1012 Key [#texture=c02/老虎钳物品.png] [#texture=c02/1012钥匙物品.png][#inspect=c02/1012钥匙.png]
29 prop_3014旋转锁钥匙 prop_老虎钳 3014旋转锁钥匙 老虎钳 [#texture=c02/3014旋转锁钥匙物品.png] [#texture=c02/老虎钳物品.png][#inspect=c02/老虎钳.png]
30 prop_小猫玩具完整 prop_3014旋转锁钥匙 小猫玩具 3014旋转锁钥匙 [#texture=c02/小猫玩具完整物品.png] [#texture=c02/3014旋转锁钥匙物品.png][#inspect=c02/3014旋转锁钥匙.png]
31 prop_小猫玩具完整 小猫玩具 [#texture=c02/小猫玩具完整物品.png][#inspect=c02/小猫玩具完整.png]
32 notes_纸条 纸条
33 notes_锁住了 锁住了
34 notes_打不开 打不开
42 c01_院长书桌 书桌上好像有本书
43 c01_院长座钟 唔...下午一点了
44 c02_绳子剪刀 绳子和剪刀
45 c02_寻人启事1 c02_寻人启事 似乎是一张寻人启事 似乎是一张寻人启事 脸的部分被撕掉了,看不清
46 c02_寻人启事2 c02_玩具缺脑袋 脸的部分被撕掉了,看不清 这个玩具缺了个脑袋
47 c02_玩具缺脑袋 c02_卫生宣传画 这个玩具缺了个脑袋 几张卫生宣传画
48 c02_卫生宣传画 c02_老鼠洞 几张卫生宣传画 一个老鼠洞 在这种楼里挺常见的
49 c02_老鼠洞1 c02_十几年前的报纸 一个老鼠洞 十几年前的报纸
50 c02_老鼠洞2 c02_又是寻人启示 在这种楼里挺常见的 又是那张寻人启示
51 c02_十几年前的报纸 c02_墙上的海报被撕掉了 十几年前的报纸 墙上的海报被撕掉了
52 c02_又是寻人启示 c02_井臭 又是那张寻人启示 井里有一股臭味
53 c02_墙上的海报被撕掉了 c02_中药材 墙上的海报被撕掉了 车上放了一些中药材
81 c02_口袋里有东西 c02_八音盒 口袋里有东西 是个八音盒
82 c02_雾太大 c02_祝女儿早日康复 雾太大了,看不清路 祝女儿早日康复
83 c02_八音盒 c02_图案一样 是个八音盒 这图案和我手臂上的一摸一样
=>en =>en
84
85
c01_获得令牌 令牌 获得 [#item]
c01_获得灵魂令牌 带有灵魂的令牌 获得 [#item]
c01_获得院长信件 院长的信件 获得 [#item]
c02_获得1012钥匙 1012钥匙 获得 [#item]
c02_获得老虎钳 老虎钳 获得 [#item]
c02_获得绳子 绳子 获得 [#item]
c02_获得小猫玩具脑袋 小猫玩具脑袋 获得 [#item]
c02_获得小猫玩具 小猫玩具 获得 [#item]
c02_获得钥匙 钥匙 获得 [#item]
c02_获得火柴 火柴 获得 [#item]
c02_1014钥匙 1014钥匙 获得 [#item]

View File

@ -1,5 +1,6 @@
# UI # UI
~ UI ~ UI
获得 [ID:ui_获得]
退出 [ID:ui_退出] 退出 [ID:ui_退出]
阅读 [ID:ui_阅读] 阅读 [ID:ui_阅读]
收起 [ID:ui_收起] 收起 [ID:ui_收起]
@ -7,273 +8,73 @@
~ PropItems ~ PropItems
# texture 路径从 "res://asset/art/prop/" 之后算起 # texture 路径从 "res://asset/art/prop/" 之后算起
空手 [ID:prop_空手]
# c01 # c01
令牌 [#texture=c01/令牌物品.png] [ID:prop_令牌] 令牌 [#texture=c01/令牌物品.png][#inspect=c01/令牌.png] [ID:prop_令牌]
装有灵魂的令牌 [#texture=c01/装有灵魂的令牌物品.png] [ID:prop_装有灵魂的令牌] 装有灵魂的令牌 [#texture=c01/装有灵魂的令牌物品.png][#inspect=c01/装有灵魂的令牌.png] [ID:prop_装有灵魂的令牌]
# c02 # c02
小猫玩具的脑袋 [#texture=c02/小猫玩具脑袋物品.png] [ID:prop_小猫玩具的脑袋] 小猫玩具的脑袋 [#texture=c02/小猫玩具脑袋物品.png][#inspect=c02/小猫玩具脑袋.png] [ID:prop_小猫玩具的脑袋]
绳子 [#texture=c02/绳子物品.png] [ID:prop_绳子] 绳子 [#texture=c02/绳子物品.png][#inspect=c02/绳子.png] [ID:prop_绳子]
1012钥匙 [#texture=c02/1012钥匙物品.png] [ID:prop_1012钥匙] 1012钥匙 [#texture=c02/1012钥匙物品.png][#inspect=c02/1012钥匙.png] [ID:prop_1012钥匙]
老虎钳 [#texture=c02/老虎钳物品.png] [ID:prop_老虎钳] 老虎钳 [#texture=c02/老虎钳物品.png][#inspect=c02/老虎钳.png] [ID:prop_老虎钳]
3014旋转锁钥匙 [#texture=c02/3014旋转锁钥匙物品.png] [ID:prop_3014旋转锁钥匙] 3014旋转锁钥匙 [#texture=c02/3014旋转锁钥匙物品.png][#inspect=c02/3014旋转锁钥匙.png] [ID:prop_3014旋转锁钥匙]
小猫玩具 [#texture=c02/小猫玩具完整物品.png] [ID:prop_小猫玩具完整] 小猫玩具 [#texture=c02/小猫玩具完整物品.png][#inspect=c02/小猫玩具完整.png] [ID:prop_小猫玩具完整]
=> END => END
# notes 通用 ~ Notes
~ notes_纸条 # 通用
纸条 [ID:notes_纸条] 纸条 [ID:notes_纸条]
=> END
~ notes_锁住了
锁住了 [ID:notes_锁住了] 锁住了 [ID:notes_锁住了]
=> END
~ notes_打不开
打不开 [ID:notes_打不开] 打不开 [ID:notes_打不开]
=> END
~ notes_干掉的血迹
干掉的血迹 [ID:notes_干掉的血迹] 干掉的血迹 [ID:notes_干掉的血迹]
=> END
~ notes_有什么东西
有什么东西 [ID:notes_有什么东西] 有什么东西 [ID:notes_有什么东西]
=> END
~ notes_无法触碰
无法触碰 [ID:notes_无法触碰] 无法触碰 [ID:notes_无法触碰]
=> END
~ notes_挂画
挂画 [ID:notes_挂画] 挂画 [ID:notes_挂画]
=> END
~ notes_相框
相框 [ID:notes_相框] 相框 [ID:notes_相框]
=> END
~ notes_寻人启事
寻人启事 [ID:notes_寻人启事] 寻人启事 [ID:notes_寻人启事]
=> END
# c01 # c01
~ c01_鸡毛掸子
这是鸡毛掸子吗? [ID:c01_鸡毛掸子] 这是鸡毛掸子吗? [ID:c01_鸡毛掸子]
=> END
~ c01_院长书桌
书桌上好像有本书 [ID:c01_院长书桌] 书桌上好像有本书 [ID:c01_院长书桌]
=> END
~ c01_院长座钟
唔...下午一点了 [ID:c01_院长座钟] 唔...下午一点了 [ID:c01_院长座钟]
=> END
# c02 # c02
~ c02_绳子剪刀
绳子和剪刀 [ID:c02_绳子剪刀] 绳子和剪刀 [ID:c02_绳子剪刀]
=> END 似乎是一张寻人启事\n脸的部分被撕掉了看不清 [ID:c02_寻人启事]
~ c02_寻人启事
似乎是一张寻人启事 [ID:c02_寻人启事1]
脸的部分被撕掉了,看不清 [ID:c02_寻人启事2]
=> END
~ c02_玩具缺脑袋
这个玩具缺了个脑袋 [ID:c02_玩具缺脑袋] 这个玩具缺了个脑袋 [ID:c02_玩具缺脑袋]
=> END
~ c02_卫生宣传画
几张卫生宣传画 [ID:c02_卫生宣传画] 几张卫生宣传画 [ID:c02_卫生宣传画]
=> END 一个老鼠洞\n在这种楼里挺常见的 [ID:c02_老鼠洞]
~ c02_老鼠洞
一个老鼠洞 [ID:c02_老鼠洞1]
在这种楼里挺常见的 [ID:c02_老鼠洞2]
=> END
~ c02_十几年前的报纸
十几年前的报纸 [ID:c02_十几年前的报纸] 十几年前的报纸 [ID:c02_十几年前的报纸]
=> END
~ c02_又是寻人启示
又是那张寻人启示 [ID:c02_又是寻人启示] 又是那张寻人启示 [ID:c02_又是寻人启示]
=> END
~ c02_墙上的海报被撕掉了
墙上的海报被撕掉了 [ID:c02_墙上的海报被撕掉了] 墙上的海报被撕掉了 [ID:c02_墙上的海报被撕掉了]
=> END
~ c02_井臭
井里有一股臭味 [ID:c02_井臭] 井里有一股臭味 [ID:c02_井臭]
=> END
~ c02_中药材
车上放了一些中药材 [ID:c02_中药材] 车上放了一些中药材 [ID:c02_中药材]
=> END
~ c02_排队
排队的人堵住了上楼的路 [ID:c02_排队] 排队的人堵住了上楼的路 [ID:c02_排队]
=> END
~ c02_不要出去
最好还是先不要出去 [ID:c02_不要出去] 最好还是先不要出去 [ID:c02_不要出去]
=> END
~ c02_太阳
太阳快落山了 [ID:c02_太阳] 太阳快落山了 [ID:c02_太阳]
=> END
~ c02_民国六年1015
民国六年十月十五日 [ID:c02_民国六年1015] 民国六年十月十五日 [ID:c02_民国六年1015]
=> END
~ c02_一个洞
一个洞,里面好像还有空间 [ID:c02_一个洞] 一个洞,里面好像还有空间 [ID:c02_一个洞]
=> END
~ c02_工具箱
工具箱 [ID:c02_工具箱] 工具箱 [ID:c02_工具箱]
=> END
~ c02_找到有用的东西
应该能找到有用的东西 [ID:c02_找到有用的东西] 应该能找到有用的东西 [ID:c02_找到有用的东西]
=> END
~ c02_公寓告示
公寓告示 [ID:c02_公寓告示] 公寓告示 [ID:c02_公寓告示]
=> END
~ c02_通往里间的门
通往里间的门 [ID:c02_通往里间的门] 通往里间的门 [ID:c02_通往里间的门]
=> END
~ c02_花名册
花名册 [ID:c02_花名册] 花名册 [ID:c02_花名册]
=> END
~ c02_罪
罪 [ID:c02_罪] 罪 [ID:c02_罪]
=> END
~ c02_门上有什么东西
门上有什么东西 [ID:c02_门上有什么东西] 门上有什么东西 [ID:c02_门上有什么东西]
=> END
~ c02_奠
奠 [ID:c02_奠] 奠 [ID:c02_奠]
=> END
~ c02_寻夏小蝉
失踪的小孩名叫夏小蝉 [ID:c02_寻夏小蝉] 失踪的小孩名叫夏小蝉 [ID:c02_寻夏小蝉]
=> END
~ c02_小猫干尸
小猫的尸体已经干了 [ID:c02_小猫干尸] 小猫的尸体已经干了 [ID:c02_小猫干尸]
=> END
~ c02_几块大洋
几块大洋 [ID:c02_几块大洋] 几块大洋 [ID:c02_几块大洋]
=> END
~ c02_死老鼠
死掉的老鼠 [ID:c02_死老鼠] 死掉的老鼠 [ID:c02_死老鼠]
=> END
~ c02_石缝开花
石缝里开了几束花 [ID:c02_石缝开花] 石缝里开了几束花 [ID:c02_石缝开花]
=> END
~ c02_石壁空间
石壁另一头好像还有空间 [ID:c02_石壁空间] 石壁另一头好像还有空间 [ID:c02_石壁空间]
=> END
~ c02_民国六年1221
民国六年十二月二十一日 [ID:c02_民国六年1221] 民国六年十二月二十一日 [ID:c02_民国六年1221]
=> END
~ c02_患者感谢信
一些患者的感谢信 [ID:c02_患者感谢信] 一些患者的感谢信 [ID:c02_患者感谢信]
=> END
~ c02_被撕掉的书
一本被撕掉的书 [ID:c02_被撕掉的书] 一本被撕掉的书 [ID:c02_被撕掉的书]
=> END
~ c02_里面有什么东西
里面有什么东西 [ID:c02_里面有什么东西] 里面有什么东西 [ID:c02_里面有什么东西]
=> END
~ c02_戏台上的诗
戏台上面刻了一首诗 [ID:c02_戏台上的诗] 戏台上面刻了一首诗 [ID:c02_戏台上的诗]
=> END
~ c02_锁开了
锁开了 [ID:c02_锁开了] 锁开了 [ID:c02_锁开了]
=> END
~ c02_口袋里有东西
口袋里有东西 [ID:c02_口袋里有东西] 口袋里有东西 [ID:c02_口袋里有东西]
=> END
~ c02_雾太大
雾太大了,看不清路 [ID:c02_雾太大] 雾太大了,看不清路 [ID:c02_雾太大]
=> END
~ c02_八音盒
是个八音盒 [ID:c02_八音盒] 是个八音盒 [ID:c02_八音盒]
=>en
~ c02_祝女儿早日康复
祝女儿早日康复 [ID:c02_祝女儿早日康复] 祝女儿早日康复 [ID:c02_祝女儿早日康复]
=> END
~ c02_图案一样
这图案和我手臂上的一摸一样 [ID:c02_图案一样] 这图案和我手臂上的一摸一样 [ID:c02_图案一样]
=> END
# 获得道具
~ c01_获得令牌
获得: 令牌 [#item] [ID:c01_获得令牌]
=> END
~ c01_获得灵魂令牌
获得: 带有灵魂的令牌 [#item] [ID:c01_获得灵魂令牌]
=> END
~ c01_获得院长信件
获得: 院长的信件 [#item] [ID:c01_获得院长信件]
=> END
~ c02_获得1012钥匙
获得: 1012钥匙 [#item] [ID:c02_获得1012钥匙]
=> END
~ c02_获得老虎钳
获得: 老虎钳 [#item] [ID:c02_获得老虎钳]
=> END
~ c02_获得绳子
获得: 绳子 [#item] [ID:c02_获得绳子]
=> END
~ c02_获得小猫玩具脑袋
获得: 小猫玩具脑袋 [#item] [ID:c02_获得小猫玩具脑袋]
=> END
~ c02_获得小猫玩具
获得: 小猫玩具 [#item] [ID:c02_获得小猫玩具]
=> END
~ c02_获得钥匙
获得: 钥匙 [#item] [ID:c02_获得钥匙]
=> END
~ c02_获得火柴
获得: 火柴 [#item] [ID:c02_获得火柴]
=> END
~ c02_1014钥匙
获得: 1014钥匙 [#item] [ID:c02_1014钥匙]
=> END => END

File diff suppressed because one or more lines are too long

View File

@ -49,7 +49,8 @@
"c02_黑手_捂屏幕": "", "c02_黑手_捂屏幕": "",
"c02_吕萍_爬行_idle_l": "", "c02_吕萍_爬行_idle_l": "",
"c02_吕萍_爬行_idle_r": "", "c02_吕萍_爬行_idle_r": "",
"c02_吕萍_爬行_left": "" "c02_吕萍_爬行_left": "",
"c01_信碎片_falling": ""
}, },
"mirror_mapping": { "mirror_mapping": {
"c00_吕萍_idle_left": "", "c00_吕萍_idle_left": "",
@ -101,7 +102,8 @@
"c02_黑手_捂屏幕": "", "c02_黑手_捂屏幕": "",
"c02_吕萍_爬行_idle_l": "", "c02_吕萍_爬行_idle_l": "",
"c02_吕萍_爬行_idle_r": "", "c02_吕萍_爬行_idle_r": "",
"c02_吕萍_爬行_left": "" "c02_吕萍_爬行_left": "",
"c01_信碎片_falling": ""
}, },
"dirs": { "dirs": {
"c00_吕萍_idle_left": { "c00_吕萍_idle_left": {
@ -379,6 +381,33 @@
"8" "8"
] ]
}, },
"c01_信碎片_falling": {
"path": "res://asset/art/animation/c01_信碎片_falling",
"frames": {
"1": "res://asset/art/animation/c01_信碎片_falling/1.png",
"10": "res://asset/art/animation/c01_信碎片_falling/10.png",
"2": "res://asset/art/animation/c01_信碎片_falling/2.png",
"3": "res://asset/art/animation/c01_信碎片_falling/3.png",
"4": "res://asset/art/animation/c01_信碎片_falling/4.png",
"5": "res://asset/art/animation/c01_信碎片_falling/5.png",
"6": "res://asset/art/animation/c01_信碎片_falling/6.png",
"7": "res://asset/art/animation/c01_信碎片_falling/7.png",
"8": "res://asset/art/animation/c01_信碎片_falling/8.png",
"9": "res://asset/art/animation/c01_信碎片_falling/9.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10"
]
},
"c01_捡球男孩_关键帧": { "c01_捡球男孩_关键帧": {
"path": "res://asset/art/animation/c01_捡球男孩_关键帧", "path": "res://asset/art/animation/c01_捡球男孩_关键帧",
"frames": { "frames": {
@ -1357,7 +1386,8 @@
"c02_黑手_捂屏幕": "c02_黑手_捂屏幕", "c02_黑手_捂屏幕": "c02_黑手_捂屏幕",
"c02_吕萍_爬行_idle_l": "laying_stay_l", "c02_吕萍_爬行_idle_l": "laying_stay_l",
"c02_吕萍_爬行_idle_r": "laying_stay_r", "c02_吕萍_爬行_idle_r": "laying_stay_r",
"c02_吕萍_爬行_left": "laying_moving_l" "c02_吕萍_爬行_left": "laying_moving_l",
"c01_信碎片_falling": "c01_信碎片_falling"
}, },
"frames_per_second": { "frames_per_second": {
"c00_吕萍_idle_left": 2, "c00_吕萍_idle_left": 2,
@ -1409,6 +1439,7 @@
"c02_黑手_捂屏幕": 9, "c02_黑手_捂屏幕": 9,
"c02_吕萍_爬行_idle_l": 2, "c02_吕萍_爬行_idle_l": 2,
"c02_吕萍_爬行_idle_r": 2, "c02_吕萍_爬行_idle_r": 2,
"c02_吕萍_爬行_left": 6 "c02_吕萍_爬行_left": 6,
"c01_信碎片_falling": 7
} }
} }

View File

@ -1,40 +0,0 @@
class_name SceneConfig extends Resource
const FOOTSTEP_AUDIO = {
#"wood": preload("res://config/audio/footstep/footstep_wood.tres"),
#"carpet": preload("res://config/audio/footstep/footstep_carpet.tres"),
"concrete": preload("res://config/audio/footstep/footstep_concrete.tres"),
#"grass": preload("res://config/audio/footstep/footstep_grass.tres"),
#"snow": preload("res://config/audio/footstep/footstep_snow.tres"),
"ghost": preload("res://config/audio/sfx/footstep_ghost.tres"),
"walking": preload("res://config/audio/sfx/footstep_walking.tres"),
"running": preload("res://config/audio/sfx/footstep_running.tres"),
"crawling": preload("res://config/audio/sfx/footstep_crawling.tres"),
}
# @export var scene_name: String = ""
# @export var boarder: PackedVector2Array
@export_group("Player", "player_")
@export var player_y_fixed := true
@export var player_y := 45
@export_group("Sound")
@export_enum("none", "ghost", "walking", "running", "crawling", "concrete")
var footstep_type: String = "concrete"
@export var bgm := ""
# @export_group("Light")
# @export var light_color := Color8(0x5e, 0x72, 0xe1, 0xff)
## ground
# @export var foreground_scale: Vector2 = Vector2(1.2, 1.2)
# @export var foreground_position: Vector2 = Vector2(0, 0)
# @export var foreground_scene: PackedScene
# @export var background_scale: Vector2 = Vector2(1.0, 1.0)
# @export var background_position: Vector2 = Vector2(0, 0)
# @export var background_scene: PackedScene
## player and camera
# @export var player_initial_position: Vector2 = Vector2(300, 186)
# @export var player_initial_direction: Vector2 = Vector2(1, -1)
# @export var player_movement_rect: Rect2 = Rect2(0, 0, 0, 0)
# @export var camera_rect: Rect2 = Rect2(0, -1000, 664, 2317) # 564*317, 16:9

View File

@ -11,9 +11,10 @@ class_name GameEvent extends Resource
# * 事件订阅机制:订阅开始/进度/成功/失败,触发特定响应 # * 事件订阅机制:订阅开始/进度/成功/失败,触发特定响应
# * 消费器能力:执行 CG锁定/无锁定,剧本/特效) / 执行实体变化脚本(赠送/消耗/状态变化) # * 消费器能力:执行 CG锁定/无锁定,剧本/特效) / 执行实体变化脚本(赠送/消耗/状态变化)
# * 保存与加载 # * 保存与加载
@export var event_id: int
@export var packed_time: PackedTime @export var packed_time: PackedTime
@export var scene: String @export var ground: String
@export var scene_position: Vector2 @export var ground_position: Vector2
@export var entity: String @export var entity: String
@export var entity_action: String @export var entity_action: String
@export var need_to_save := false
@export var extra_data = {}

View File

@ -2,42 +2,39 @@ class_name GameEventMatcher extends Resource
# match event under certain conditions # match event under certain conditions
# regex matcher, "[chapter]_[section]", * means any
# e.g. 3_* means any section in chapter 3
# empty means any ground
@export var grounds: Array[String]
# can't be empty # can't be empty
@export var entity: String @export var entity: String
# empty means any action # empty means any action
@export var entity_actions: Array[String] @export var entity_actions: Array[String]
# empty means any scene
@export var scenes: Array[String]
# regex matcher, "[chapter]_[section]", * means any
# e.g. 3_* means any section in chapter 3
# empty means any chapter_section
@export var chapter_section: Array[String]
# check if the event matches the conditions # check if the event matches the conditions
func match(event: GameEvent) -> bool: func match(event: GameEvent) -> bool:
if !entity or entity != event.entity: if !entity or entity != event.entity:
return false return false
if entity_actions.size() > 0 and !entity_actions.has(event.entity_action): if entity_actions.size() > 0 and !entity_actions.has(event.entity_action):
return false return false
if scenes.size() > 0 and !scenes.has(event.scene): if grounds.size() > 0:
return false var chapter := str(event.packed_time.chapter)
if chapter_section.size() > 0: var section := str(event.packed_time.section)
var chapter := str(event.packed_time.chapter) var matched := false
var section := str(event.packed_time.section) for ground_matcher in grounds:
var matched := false # regex match
for chapter_section_matcher in chapter_section: var parts = ground_matcher.split("_")
# regex match if parts.size() != 2:
var parts = chapter_section_matcher.split("_") continue
if parts.size() != 2: var chapter_matcher = parts[0].strip_edges()
continue var section_matcher = parts[1].strip_edges()
var chapter_matcher = parts[0] if (
var section_matcher = parts[1] (chapter_matcher == "*" or chapter_matcher == chapter)
if chapter_matcher == "*" or chapter_matcher == chapter: and (section_matcher == "*" or section_matcher == section)
matched = true ):
break matched = true
if section_matcher == "*" or section_matcher == section: break
matched = true if !matched:
break return false
if !matched: return true
return false
return true

View File

@ -16,9 +16,13 @@ func get_player() -> MainPlayer:
return get_node_or_null("/root/Main/MainPlayer") as MainPlayer return get_node_or_null("/root/Main/MainPlayer") as MainPlayer
func get_current_selected_prop() -> String: func get_prop_hud() -> PropHud:
var prop_hud = get_node_or_null("/root/Main/UILayer/PropHUD") as PropHud return get_node_or_null("/root/Main/UILayer/PropHUD") as PropHud
if prop_hud and prop_hud.selected:
func get_current_prop(must_selected: bool) -> String:
var prop_hud = get_prop_hud()
if prop_hud and (not must_selected or prop_hud.selected):
return prop_hud.inventory.current_item_key() return prop_hud.inventory.current_item_key()
return "" return ""

View File

@ -4,13 +4,16 @@ extends Node
# { entity: [MatcherConsumer] } # { entity: [MatcherConsumer] }
var _event_registry: Dictionary = {} var _event_registry: Dictionary = {}
class MatcherConsumer extends RefCounted:
var _matcher: GameEventMatcher
var _consumer: Callable
func _init(matcher: GameEventMatcher, consumer: Callable) -> void: class MatcherConsumer:
self._matcher = matcher extends RefCounted
self._consumer = consumer @export var matcher: GameEventMatcher
@export var consumer: Callable
func _init(m: GameEventMatcher, c: Callable) -> void:
self.matcher = m
self.consumer = c
# 注册事件 # 注册事件
func register_event_matcher(event_matcher: GameEventMatcher, consumer: Callable) -> void: func register_event_matcher(event_matcher: GameEventMatcher, consumer: Callable) -> void:
@ -21,6 +24,7 @@ func register_event_matcher(event_matcher: GameEventMatcher, consumer: Callable)
_event_registry[event_matcher.entity] = [] _event_registry[event_matcher.entity] = []
_event_registry[event_matcher.entity].append(matcher_consumer) _event_registry[event_matcher.entity].append(matcher_consumer)
# 触发事件 # 触发事件
func trigger_event(event: GameEvent) -> void: func trigger_event(event: GameEvent) -> void:
if event.entity not in _event_registry: if event.entity not in _event_registry:
@ -29,3 +33,15 @@ func trigger_event(event: GameEvent) -> void:
# matcher_consumer = matcher_consumer as MatcherConsumer # matcher_consumer = matcher_consumer as MatcherConsumer
if matcher_consumer._matcher.match(event): if matcher_consumer._matcher.match(event):
matcher_consumer._consumer.call(event) matcher_consumer._consumer.call(event)
if event.need_to_save:
_save_event(event)
func _save_event(event) -> void:
# 保存事件
pass
func prop_interacted(name, prop_key, interacted_times) -> void:
print("Event: %s interacted with %s. total times: %s" % [name, prop_key, interacted_times])
pass

View File

@ -63,7 +63,6 @@ window/size/window_width_override=1692
window/size/window_height_override=948 window/size/window_height_override=948
window/subwindows/embed_subwindows=false window/subwindows/embed_subwindows=false
window/stretch/mode="canvas_items" window/stretch/mode="canvas_items"
window/stretch/scale_mode="integer"
[editor_plugins] [editor_plugins]

View File

@ -4,7 +4,7 @@
[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(40, 70) size = Vector2(10, 70)
[node name="Ambush" type="Node2D"] [node name="Ambush" type="Node2D"]
script = ExtResource("1_rxgbr") script = ExtResource("1_rxgbr")

View File

@ -7,7 +7,7 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_gffp4"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_gffp4"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(35, 70) size = Vector2(20, 70)
[node name="HdEntity" type="Marker2D"] [node name="HdEntity" type="Marker2D"]
script = ExtResource("1_fp2a8") script = ExtResource("1_fp2a8")

View File

@ -3,14 +3,16 @@ extends Sprite2D
signal interacted(success: bool) signal interacted(success: bool)
@export var entity_name: String = "" @export var unmatched_sign_texture: Texture2D
@export var matched_sign_texture: Texture2D
@export var texture_before: Texture2D @export var texture_before: Texture2D
@export var texture_after: Texture2D @export var texture_after: Texture2D
@export var one_shot := true @export var one_shot := true
@export var interacted_times := 0 @export var interacted_times := 0
var prop_key := "" var prop_key := ""
@onready var sfx = $Sfx as Sfx @onready var sfx_invalid = $SfxInvalid as Sfx
@onready var sfx_success = $SfxSuccess as Sfx
@onready var sign_mark = %Sign as Sign @onready var sign_mark = %Sign as Sign
@onready var area2d = %Area2D as Area2D @onready var area2d = %Area2D as Area2D
@ -42,29 +44,61 @@ func _ready() -> void:
area2d.body_exited.connect(_on_cancel) area2d.body_exited.connect(_on_cancel)
sign_mark.interacted.connect(_on_interacted) sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel) sign_mark.cancel.connect(_on_cancel)
sign_mark.base_scale = sign_mark.scale
func _reset(_body = null) -> void: func _reset(_body = null) -> void:
pass var key = SceneManager.get_current_prop(false)
if key:
_set_sign_texture_to_prop(key)
var prop_hud = SceneManager.get_prop_hud() as PropHud
if not prop_hud.current_item_changed.is_connected(_set_sign_texture_to_prop):
prop_hud.current_item_changed.connect(_set_sign_texture_to_prop)
# 根据当前 prop调整 sign 所显示的 texture
func _set_sign_texture_to_prop(key):
if prop_key == key:
sign_mark.sprite2d.texture = matched_sign_texture
else:
sign_mark.sprite2d.texture = unmatched_sign_texture
# if prop_hud.cached_inventory_textures.has(key):
# var prop_texture = prop_hud.cached_inventory_textures[key]
# sign_mark.draw_shadow = true
# else:
# sign_mark.sprite2d.texture = deaulte_sign_texture
# sign_mark.draw_shadow = false
# sign_mark.queue_redraw()
func _on_cancel(_body = null) -> void: func _on_cancel(_body = null) -> void:
pass # disconnect signal
var prop_hud = SceneManager.get_prop_hud() as PropHud
if prop_hud and prop_hud.current_item_changed.is_connected(_set_sign_texture_to_prop):
prop_hud.current_item_changed.disconnect(_set_sign_texture_to_prop)
func _on_interacted() -> void: func _on_interacted() -> void:
if one_shot and interacted_times: if one_shot and interacted_times:
return return
sfx.play() var key = SceneManager.get_current_prop(false)
var key = SceneManager.get_current_selected_prop() var prop_hud = SceneManager.get_prop_hud() as PropHud
# print("prop_key", key)
if key != prop_key: if key != prop_key:
sfx_invalid.play()
sign_mark.invalid_shake()
# prop_hud.on_toggle_invalid_prop()
return return
sfx_success.play()
if one_shot:
prop_hud.disable_prop_item(prop_key)
else:
prop_hud.on_toggle_valid_prop()
interacted_times += 1 interacted_times += 1
if texture_after: if texture_after:
texture = texture_after texture = texture_after
interacted.emit() interacted.emit()
print("%s interacted with %s" % [entity_name, prop_key]) EventManager.prop_interacted(name, prop_key, interacted_times)
# print("%s interacted with %s. total times: %s" % [name, prop_key, interacted_times])
func _get_property_list() -> Array[Dictionary]: func _get_property_list() -> Array[Dictionary]:

View File

@ -1,8 +1,19 @@
[gd_scene load_steps=5 format=3 uid="uid://cw3q5pvciumil"] [gd_scene load_steps=10 format=3 uid="uid://cw3q5pvciumil"]
[ext_resource type="Script" path="res://scene/entity/interactable.gd" id="1_6nrd3"] [ext_resource type="Script" path="res://scene/entity/interactable.gd" id="1_6nrd3"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="2_bvj74"] [ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="2_bvj74"]
[ext_resource type="Texture2D" uid="uid://dauxagpmoc58x" path="res://asset/art/ui/互动提示符/ui 像素版_纯白.png" id="2_tvf5d"]
[ext_resource type="AudioStream" uid="uid://duwf0mdrvngvr" path="res://asset/audio/sfx/ui/开锁声.mp3" id="3_o5jv1"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="3_qsms8"] [ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="3_qsms8"]
[ext_resource type="AudioStream" uid="uid://cy56cat5jt1pi" path="res://asset/audio/sfx/ui/钥匙.mp3" id="3_tq35w"]
[sub_resource type="AtlasTexture" id="AtlasTexture_0gwq7"]
atlas = ExtResource("2_tvf5d")
region = Rect2(762, 468, 63, 63)
[sub_resource type="AtlasTexture" id="AtlasTexture_0ks5m"]
atlas = ExtResource("2_tvf5d")
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
@ -10,14 +21,24 @@ size = Vector2(35, 70)
[node name="Interactable" type="Sprite2D"] [node name="Interactable" type="Sprite2D"]
script = ExtResource("1_6nrd3") script = ExtResource("1_6nrd3")
unmatched_sign_texture = SubResource("AtlasTexture_0gwq7")
matched_sign_texture = SubResource("AtlasTexture_0ks5m")
prop_key = "" prop_key = ""
[node name="Sfx" parent="." instance=ExtResource("2_bvj74")] [node name="SfxInvalid" parent="." instance=ExtResource("2_bvj74")]
stream = ExtResource("3_tq35w")
file = "钥匙.mp3"
[node name="SfxSuccess" parent="." instance=ExtResource("2_bvj74")]
stream = ExtResource("3_o5jv1")
file = "开锁声.mp3" file = "开锁声.mp3"
[node name="Sign" parent="." instance=ExtResource("3_qsms8")] [node name="Sign" parent="." instance=ExtResource("3_qsms8")]
unique_name_in_owner = true unique_name_in_owner = true
[node name="Sprite2D" parent="Sign/TextureContainer" index="0"]
texture = SubResource("AtlasTexture_0gwq7")
[node name="Area2D" type="Area2D" parent="."] [node name="Area2D" type="Area2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
collision_layer = 0 collision_layer = 0
@ -25,3 +46,5 @@ collision_layer = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
unique_name_in_owner = true unique_name_in_owner = true
shape = SubResource("RectangleShape2D_8d3b4") shape = SubResource("RectangleShape2D_8d3b4")
[editable path="Sign"]

View File

@ -42,13 +42,14 @@ var inspected_time = 0.0
func _ready() -> void: func _ready() -> void:
$InspectLayer.layer = GlobalConfig.CANVAS_LAYER_PROP_INSPECTOR $InspectLayer.layer = GlobalConfig.CANVAS_LAYER_PROP_INSPECTOR
sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel)
container.modulate.a = 0.0 container.modulate.a = 0.0
content_label.text = _get_tr_content() content_label.text = _get_tr_content()
tip_label.text = tip_cover tip_label.text = tip_cover
cover_rect.texture = texture_cover cover_rect.texture = texture_cover
if Engine.is_editor_hint():
return
sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel)
func _get_tr_content(): func _get_tr_content():
if content_key == "": if content_key == "":

View File

@ -10,7 +10,7 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(35, 70) size = Vector2(20, 70)
[sub_resource type="LabelSettings" id="LabelSettings_c3c2j"] [sub_resource type="LabelSettings" id="LabelSettings_c3c2j"]
line_spacing = 1.0 line_spacing = 1.0
@ -27,8 +27,8 @@ file = "纸条.mp3"
[node name="Sign" parent="." instance=ExtResource("4_do8tr")] [node name="Sign" parent="." instance=ExtResource("4_do8tr")]
unique_name_in_owner = true unique_name_in_owner = true
offset_top = -8.0 offset_top = -14.0
offset_bottom = 72.0 offset_bottom = -14.0
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -17,9 +17,9 @@ signal read_note
if is_node_ready(): if is_node_ready():
notify_property_list_changed() notify_property_list_changed()
var note_key := "" var note_key := ""
@export_enum("none", "notes", "c01", "c02", "c03", "c04", "c05", "c06") var editor_filter := "none": @export_enum("none", "notes", "c01", "c02", "c03", "c04", "c05", "c06") var title_filter := "none":
set(val): set(val):
editor_filter = val title_filter = val
if is_node_ready(): if is_node_ready():
notify_property_list_changed() notify_property_list_changed()
@ -52,31 +52,39 @@ func _on_interacted() -> void:
printerr("Note key is not set") printerr("Note key is not set")
return return
%Sfx.play() %Sfx.play()
var _res = dialogue_res
var title = note_key
# items 条目特殊处理,不使用标题
if dialogue == "items":
title = "start"
var content = tr(note_key)
var text = "~ " + title + "\n" + content + "\n=> END"
_res = DialogueManager.create_resource_from_text(text) as DialogueResource
match mode: match mode:
"os": "os":
_show_os() _show_os(_res, title)
"ballon": "ballon":
_show_balloon() _show_balloon(_res, title)
read_note.emit() read_note.emit()
func _show_os(): func _show_os(res, title):
var lines = [] var lines = []
var current_line = await dialogue_res.get_next_dialogue_line(note_key) var current_line = await res.get_next_dialogue_line(title)
while current_line: while current_line:
lines.append(current_line) lines.append(current_line)
if current_line.next_id != "end": if current_line.next_id != "end":
current_line = await dialogue_res.get_next_dialogue_line(current_line.next_id) current_line = await res.get_next_dialogue_line(current_line.next_id)
else: else:
break break
SceneManager.pop_os(lines) SceneManager.pop_os(lines)
SceneManager.freeze_player(1.0, "") SceneManager.freeze_player(1.0, "")
func _show_balloon(): func _show_balloon(res, title):
# SceneManager.focus_node(self) # SceneManager.focus_node(self)
# CameraFocusMarker.tween_zoom(1.1, 1.5) # CameraFocusMarker.tween_zoom(1.1, 1.5)
DialogueManager.show_dialogue_balloon(dialogue_res, note_key) 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
@ -109,11 +117,23 @@ func _get(property: StringName) -> Variant:
func _get_property_list() -> Array[Dictionary]: func _get_property_list() -> Array[Dictionary]:
# only show notes_ properties in editor # only show notes_ properties in editor
var titles = "" var titles = ""
if Engine.is_editor_hint() and editor_filter and editor_filter != "none": var title_arr = []
var filted_titles = dialogue_res.get_ordered_titles().filter(_filter_property) if dialogue == "items":
var id = dialogue_items.titles["Notes"]
var current_line = dialogue_items.lines[id]
while current_line:
if current_line.has("translation_key"):
title_arr.append(current_line.translation_key)
if not current_line.has("next_id") or current_line.next_id == "end":
break
current_line = dialogue_items.lines[current_line.next_id]
else:
title_arr = dialogue_res.get_ordered_titles()
if Engine.is_editor_hint() and title_filter and title_filter != "none":
var filted_titles = title_arr.filter(_filter_property)
titles = ",".join(filted_titles) titles = ",".join(filted_titles)
else: else:
titles = ",".join(dialogue_res.get_ordered_titles()) titles = ",".join(title_arr)
return [ return [
{ {
"name": "note_key", "name": "note_key",
@ -125,7 +145,7 @@ func _get_property_list() -> Array[Dictionary]:
func _filter_property(property: StringName) -> bool: func _filter_property(property: StringName) -> bool:
return property.find(editor_filter) >= 0 return property.find(title_filter) >= 0
func _on_cancel(_body = null): func _on_cancel(_body = null):

View File

@ -8,7 +8,7 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_k6och"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_k6och"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(40, 60) size = Vector2(20, 60)
[node name="Note" type="Sprite2D"] [node name="Note" type="Sprite2D"]
script = ExtResource("1_3igk8") script = ExtResource("1_3igk8")

View File

@ -78,7 +78,7 @@ size = Vector2(61, 112.75)
[node name="Npc" type="AnimatedSprite2D"] [node name="Npc" type="AnimatedSprite2D"]
sprite_frames = ExtResource("3_1e8sl") sprite_frames = ExtResource("3_1e8sl")
animation = &"c02_张胖子_idle" animation = &"c02_张胖子_idle"
frame_progress = 0.195431 frame_progress = 0.83643
script = ExtResource("1_jegr2") script = ExtResource("1_jegr2")
dialogue_title = "" dialogue_title = ""

View File

@ -42,7 +42,7 @@ func _on_interacted() -> void:
if not texture_note: if not texture_note:
texture_note = texture_cover texture_note = texture_cover
var inspection_note = _get_tr_content() var inspection_note = _get_tr_content()
inspector.pop_inspection(texture_cover, texture_note, inspection_note) inspector.pop_standard_inspection(texture_cover, texture_note, inspection_note)
inspecting = true inspecting = true
sign_mark.show_sign = false sign_mark.show_sign = false

View File

@ -22,8 +22,10 @@ file = "物品查看.mp3"
[node name="Sign" parent="." instance=ExtResource("4_1yty8")] [node name="Sign" parent="." instance=ExtResource("4_1yty8")]
unique_name_in_owner = true unique_name_in_owner = true
offset_top = -7.0 offset_left = -0.5
offset_bottom = 73.0 offset_top = -10.5
offset_right = -0.5
offset_bottom = 69.5
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -20,10 +20,10 @@ file = "令牌道具获取.wav"
[node name="Sign" parent="." instance=ExtResource("4_44f4h")] [node name="Sign" parent="." instance=ExtResource("4_44f4h")]
unique_name_in_owner = true unique_name_in_owner = true
offset_left = 1.0 offset_left = -0.5
offset_top = -35.0 offset_top = -24.5
offset_right = 1.0 offset_right = -0.5
offset_bottom = -35.0 offset_bottom = -24.5
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -8,7 +8,7 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_munml"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_munml"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(45, 130) size = Vector2(25, 130)
[node name="portal_left" type="Sprite2D"] [node name="portal_left" type="Sprite2D"]
script = ExtResource("1_jyh6v") script = ExtResource("1_jyh6v")
@ -20,10 +20,13 @@ file = "页面转换声.wav"
[node name="Sign" parent="." instance=ExtResource("4_ty1ds")] [node name="Sign" parent="." instance=ExtResource("4_ty1ds")]
unique_name_in_owner = true unique_name_in_owner = true
offset_top = -63.0 offset_top = -67.5
offset_right = 347.0 offset_right = 347.0
offset_bottom = 271.0 offset_bottom = 266.5
scale = Vector2(0.05, 0.05) scale = Vector2(0.05, 0.05)
[node name="Sprite2D" parent="Sign/TextureContainer" index="0"]
position = Vector2(0, 10)
texture = ExtResource("2_ay30q") texture = ExtResource("2_ay30q")
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
@ -39,3 +42,5 @@ unique_name_in_owner = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_munml") shape = SubResource("RectangleShape2D_munml")
[editable path="Sign"]

View File

@ -1,14 +1,6 @@
@tool @tool
class_name Sign extends TextureRect class_name Sign extends Control
# @export var texture: Texture:
# set(val):
# texture = val
# sprite2d.texture = texture
# # @export var base_scale := Vector2.ONE:
# # set(val):
# # base_scale = val
# # sprite2d.scale = base_scale
@export var show_sign := true: @export var show_sign := true:
set(val): set(val):
show_sign = val show_sign = val
@ -16,17 +8,26 @@ class_name Sign extends TextureRect
modulate.a = 1.0 modulate.a = 1.0
else: else:
modulate.a = 0.0 modulate.a = 0.0
@export var draw_shadow := false
signal interacted signal interacted
signal cancel signal cancel
@onready var texture_container = %TextureContainer as Container
@onready var sprite2d = %Sprite2D as Sprite2D
# var shadow_texture = preload("res://asset/art/ui/action_mark/探索空心ui.png") as Texture2D
# 同时只能有一个物品被激活交互态,其他物品进入等待队列 # 同时只能有一个物品被激活交互态,其他物品进入等待队列
static var occupied: NodePath static var occupied: NodePath
static var _pending_activate_sign := [] as Array[NodePath] static var _pending_activate_sign := [] as Array[NodePath]
# 使用互斥锁保证线程安全。在操作 occupied 或 _pending_activate_sign 时需要先锁定,操作完成后解锁 # 使用互斥锁保证线程安全。在操作 occupied 或 _pending_activate_sign 时需要先锁定,操作完成后解锁
static var mutex = Mutex.new() static var mutex = Mutex.new()
var activated = false var activated = false:
set(val):
activated = val
queue_redraw()
# var sprite2d = Sprite2D.new() # var sprite2d = Sprite2D.new()
var base_scale = Vector2.ONE var base_scale = Vector2.ONE
@ -45,11 +46,6 @@ func _ready() -> void:
modulate.a = 0 modulate.a = 0
# func _load_sprite() -> void:
# sprite2d.texture = texture
# sprite2d.scale = base_scale
func activate(_body: Node2D) -> void: func activate(_body: Node2D) -> void:
# point_light.energy = 1.0 # point_light.energy = 1.0
if not is_node_ready(): if not is_node_ready():
@ -71,12 +67,32 @@ func activate(_body: Node2D) -> void:
p_tween.tween_property(self, "scale", base_scale * Vector2(1.2, 1.2), 0.3) p_tween.tween_property(self, "scale", base_scale * Vector2(1.2, 1.2), 0.3)
p_tween.tween_property(self, "scale", base_scale, 0.1) p_tween.tween_property(self, "scale", base_scale, 0.1)
# if activated: # if activated:
# focus_mode = FOCUS_ALL # focus_mode = FOCUS_ALL
# grab_focus() # grab_focus()
# 绘制 prop 图标
# func _draw() -> void:
# if draw_shadow and sprite2d.texture:
# var texture_x = sprite2d.texture.get_size().x
# # var radius = max(36.0, min(texture_x * 0.5, 48.0))
# var radius = 46.0
# var rect = Rect2(-radius, -radius, radius * 2, radius * 2)
# draw_texture_rect(shadow_texture, rect, false)
# # 比 2.0 略小,选择使用 1.6
# var texture_scale = min(radius * 1.6 / texture_x, 1.1)
# sprite2d.scale = Vector2(texture_scale, texture_scale)
# # var texture_radius = shadow_texture.x * 0.5
# # draw_circle(Vector2.ZERO, radius, Color(0.8, 0.8, 0.8, 0.8), false, 6.0, true)
# # radius -= 6.0
# # if radius > 0:
# # draw_circle(Vector2.ZERO, radius, Color(0.3, 0.3, 0.3, 0.3))
# else:
# sprite2d.scale = Vector2.ONE
func disactivate(_body: Node2D) -> void: func disactivate(_body: Node2D) -> void:
# release_focus() # release_focus()d
mutex.lock() mutex.lock()
if activated: if activated:
activated = false activated = false
@ -114,3 +130,30 @@ func _unhandled_input(event: InputEvent) -> void:
var viewport = get_viewport() var viewport = get_viewport()
if viewport: if viewport:
viewport.set_input_as_handled() viewport.set_input_as_handled()
var shake_tween
# 使用无效道具,抖动提示
func invalid_shake():
if shake_tween:
shake_tween.kill()
# 抖动效果,逐渐减弱
shake_tween = create_tween()
var fps := 12.0
var duration := 0.7
var delta := 4.0
var origin_pos = Vector2.ZERO
var count = int(duration * fps)
var delta_t = 1.0 / fps
sprite2d.modulate = Color(1.0, 0.6, 0.6, 1.0)
for i in range(count):
var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta)) * exp(-i)
shake_tween.tween_property(sprite2d, "position", origin_pos + offset, delta_t).set_trans(
Tween.TRANS_CUBIC
)
shake_tween.tween_callback(_reset_modulate)
func _reset_modulate():
sprite2d.modulate = Color(1.0, 1.0, 1.0, 1.0)

View File

@ -3,13 +3,26 @@
[ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="1_40b58"] [ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="1_40b58"]
[ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="2_kaoka"] [ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="2_kaoka"]
[node name="Sign" type="TextureRect"] [node name="Sign" type="Control"]
offset_right = 83.0 layout_mode = 3
offset_bottom = 80.0 anchors_preset = 0
scale = Vector2(0.2, 0.2) scale = Vector2(0.2, 0.2)
pivot_offset = Vector2(-10, -10)
size_flags_horizontal = 4 size_flags_horizontal = 4
size_flags_vertical = 4 size_flags_vertical = 4
mouse_filter = 2 mouse_filter = 2
texture = ExtResource("1_40b58")
script = ExtResource("2_kaoka") script = ExtResource("2_kaoka")
[node name="TextureContainer" type="CenterContainer" parent="."]
unique_name_in_owner = true
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="Sprite2D" type="Sprite2D" parent="TextureContainer"]
unique_name_in_owner = true
position = Vector2(3.8147e-06, 3.8147e-06)
texture = ExtResource("1_40b58")

View File

@ -1,25 +1,34 @@
@tool @tool
class_name Ground2D extends Node2D class_name Ground2D extends Node2D
@export var scene_config: SceneConfig @export_group("Player", "player_")
# @export var build_boarder := false: @export var player_y_fixed := true
# set(new_val): @export var player_y := 45
# build_boarder = false @export_group("Sound")
# _build_boarder() @export_enum("none", "ghost", "walking", "running", "crawling", "concrete")
@export var reload := false: var footstep_type: String = "concrete":
set(new_val): set(val):
reload = false footstep_type = val
load_config() if is_node_ready():
_load_footstep_audio()
@onready var directional_light := %DirectionalLight2D as DirectionalLight2D @onready var directional_light := %DirectionalLight2D as DirectionalLight2D
@onready var foreground = %ParallaxForeground as ParallaxBackground @onready var foreground = %ParallaxForeground as ParallaxBackground
var footstep_audio = RandomAudioStreamPlayer.new() var footstep_audio = RandomAudioStreamPlayer.new()
const FOOTSTEP_AUDIO = {
func play_footstep_sound() -> void: #"wood": preload("res://config/audio/footstep/footstep_wood.tres"),
if not footstep_audio.audio_collections.is_empty(): #"carpet": preload("res://config/audio/footstep/footstep_carpet.tres"),
footstep_audio.play_random() "concrete": preload("res://config/audio/footstep/footstep_concrete.tres"),
#"grass": preload("res://config/audio/footstep/footstep_grass.tres"),
#"snow": preload("res://config/audio/footstep/footstep_snow.tres"),
"ghost": preload("res://config/audio/sfx/footstep_ghost.tres"),
"walking": preload("res://config/audio/sfx/footstep_walking.tres"),
"running": preload("res://config/audio/sfx/footstep_running.tres"),
"crawling": preload("res://config/audio/sfx/footstep_crawling.tres"),
}
func _ready() -> void: func _ready() -> void:
@ -27,37 +36,17 @@ func _ready() -> void:
# %ColorRectTop.visible = true # %ColorRectTop.visible = true
# %ColorRectBottom.visible = true # %ColorRectBottom.visible = true
add_child(footstep_audio) add_child(footstep_audio)
load_config() _load_footstep_audio()
func load_config(): func _load_footstep_audio():
if not scene_config:
return
var type = scene_config.footstep_type
# foot step sound # foot step sound
footstep_audio.audio_collections.clear() footstep_audio.audio_collections.clear()
if type != "none": if footstep_type != "none":
var audio = SceneConfig.FOOTSTEP_AUDIO[type] as AudioStreamCollection var audio = FOOTSTEP_AUDIO[footstep_type] as AudioStreamCollection
footstep_audio.audio_collections.append(audio) footstep_audio.audio_collections.append(audio)
# # collision boarder
# if scene_config.boarder:
# _load_collision_boarder()
# light color
# directional_light.color = scene_config.light_color
# func _build_boarder() -> void:
# if scene_config and $BGSprite2D and $BGSprite2D.texture:
# var image = $BGSprite2D.texture.get_image()
# var origin = $BGSprite2D.position + $BGSprite2D.offset
# var points = PackedVector2Array()
# for i in range(image.get_width()):
# for j in range(image.get_height()):
# if image.get_pixel(i, j).a > 0:
# points.append(origin + Vector2(i, j))
# var boarder = Geometry2D.convex_hull(points)
# scene_config.boarder = boarder
# _load_collision_boarder()
# func _load_collision_boarder() -> void: func play_footstep_sound() -> void:
# if scene_config and scene_config.boarder and $StaticBody2D/CollisionPolygon2D: if not footstep_audio.audio_collections.is_empty():
# $StaticBody2D/CollisionPolygon2D.polygon = scene_config.boarder footstep_audio.play_random()

View File

@ -1,18 +1,9 @@
[gd_scene load_steps=7 format=3 uid="uid://dayyx4jerj7io"] [gd_scene load_steps=5 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="Script" path="res://config/deploy/scene_config.gd" id="2_bx7rv"]
[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="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"]
[sub_resource type="Resource" id="Resource_6ux50"]
resource_local_to_scene = true
script = ExtResource("2_bx7rv")
player_y_fixed = true
player_y = 45
footstep_type = "concrete"
bgm = ""
[sub_resource type="GDScript" id="GDScript_qxugl"] [sub_resource type="GDScript" id="GDScript_qxugl"]
script/source = "extends CanvasLayer script/source = "extends CanvasLayer
@ -22,7 +13,6 @@ func _ready() -> void:
[node name="Ground" type="Node2D"] [node name="Ground" type="Node2D"]
script = ExtResource("1_0vrlo") script = ExtResource("1_0vrlo")
scene_config = SubResource("Resource_6ux50")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."] [node name="AnimationPlayer" type="AnimationPlayer" parent="."]

View File

@ -13,6 +13,7 @@ class_name GroundLoader extends Node2D
@export var archive_scene := "" @export var archive_scene := ""
@export var archive_portal := "" @export var archive_portal := ""
var first_entered := true
var ground: Ground2D var ground: Ground2D
var scenes_dir = "res://scene/ground/scene/" var scenes_dir = "res://scene/ground/scene/"
@ -31,7 +32,7 @@ func _ready() -> void:
entrance_portal = archive_portal entrance_portal = archive_portal
if current_scene and entrance_portal: if current_scene and entrance_portal:
transition_to_scene(current_scene, entrance_portal, true) transition_to_scene(current_scene, entrance_portal, true)
elif ground: elif ground:
ground.queue_free() ground.queue_free()
ground = null ground = null
@ -68,7 +69,8 @@ func transition_to_scene(key: String, portal: String, immediately := false) -> v
if immediately: if immediately:
_do_transition(scene) _do_transition(scene)
# 更新玩家位置 # 更新玩家位置
_update_player_position() if first_entered:
_update_player_position()
else: else:
var tween = create_tween() as Tween var tween = create_tween() as Tween
var player = SceneManager.get_player() as MainPlayer var player = SceneManager.get_player() as MainPlayer
@ -79,6 +81,7 @@ func transition_to_scene(key: String, portal: String, immediately := false) -> v
tween.tween_interval(0.2) tween.tween_interval(0.2)
tween.tween_callback(_do_transition.bind(scene)) tween.tween_callback(_do_transition.bind(scene))
tween.tween_callback(func(): player.action_locked = false) tween.tween_callback(func(): player.action_locked = false)
first_entered = false
else: else:
print("Scene not found: " + key) print("Scene not found: " + key)
@ -92,20 +95,20 @@ func _update_player_position():
# print("update player position", ArchiveManager.archive.player_global_position) # print("update player position", ArchiveManager.archive.player_global_position)
player.global_position = ArchiveManager.archive.player_global_position player.global_position = ArchiveManager.archive.player_global_position
# fixed y # fixed y
if ground.scene_config and ground.scene_config.player_y_fixed: if ground.player_y_fixed:
player.global_position.y = ground.scene_config.player_y player.global_position.y = ground.player_y
player.set_facing_direction(ArchiveManager.archive.player_direction) player.set_facing_direction(ArchiveManager.archive.player_direction)
func _do_transition(scene: Node2D): func _do_transition(scene: Node2D):
if ground: if ground:
ground.queue_free()
# 提前移除,防止命名冲突 # 提前移除,防止命名冲突
remove_child(ground) remove_child(ground)
ground.queue_free()
ground = scene.get_child(0) ground = scene.get_child(0)
scene.remove_child(ground) scene.remove_child(ground)
scene.queue_free()
ground.owner = null ground.owner = null
scene.queue_free()
add_child(ground) add_child(ground)
ground.name = "Ground" ground.name = "Ground"
_set_camera_and_player_boundary() _set_camera_and_player_boundary()
@ -114,8 +117,12 @@ func _do_transition(scene: Node2D):
if portal_node and not Engine.is_editor_hint(): if portal_node and not Engine.is_editor_hint():
var player = SceneManager.get_player() var player = SceneManager.get_player()
if player: if player:
# player.global_position.x = -20.0
player.global_position.x = portal_node.global_position.x player.global_position.x = portal_node.global_position.x
print("move player to portal:", entrance_portal, portal_node.global_position) if GlobalConfig.DEBUG:
print("move player to portal:", entrance_portal, portal_node.global_position)
else:
printerr(current_scene + " portal not found: " + entrance_portal)
if GlobalConfig.DEBUG and not Engine.is_editor_hint(): if GlobalConfig.DEBUG and not Engine.is_editor_hint():
_watch_scene_update() _watch_scene_update()

View File

@ -1,7 +1,6 @@
[gd_scene load_steps=23 format=3 uid="uid://dlx5xxbg53rb8"] [gd_scene load_steps=22 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://config/deploy/scene_config.gd" id="2_ve5ly"]
[ext_resource type="Texture2D" uid="uid://bx5we5pgnlhl5" path="res://asset/art/scene/c01/s05_院长房间/bg_房间背景.png" id="3_3r1q2"] [ext_resource type="Texture2D" uid="uid://bx5we5pgnlhl5" path="res://asset/art/scene/c01/s05_院长房间/bg_房间背景.png" id="3_3r1q2"]
[ext_resource type="Texture2D" uid="uid://dkufmwg07maun" path="res://asset/art/scene/c01/s05_院长房间/全局参考.png" id="3_7u4bh"] [ext_resource type="Texture2D" uid="uid://dkufmwg07maun" path="res://asset/art/scene/c01/s05_院长房间/全局参考.png" id="3_7u4bh"]
[ext_resource type="Texture2D" uid="uid://bp2r4s6v6ag2f" path="res://asset/art/scene/c01/s05_院长房间/fg_前景.png" id="3_vmr0f"] [ext_resource type="Texture2D" uid="uid://bp2r4s6v6ag2f" path="res://asset/art/scene/c01/s05_院长房间/fg_前景.png" id="3_vmr0f"]
@ -16,15 +15,8 @@
[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="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="Texture2D" uid="uid://cyqnkcx3qx100" path="res://asset/art/scene/c01/s05_院长房间/l_房间背景.png" id="15_6p040"] [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"]
[sub_resource type="Resource" id="Resource_6jwab"]
resource_local_to_scene = true
script = ExtResource("2_ve5ly")
player_y_fixed = true
player_y = 45
footstep_type = "concrete"
bgm = ""
[sub_resource type="RectangleShape2D" id="RectangleShape2D_6i5gw"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_6i5gw"]
resource_local_to_scene = true resource_local_to_scene = true
@ -45,7 +37,6 @@ 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")]
scene_config = SubResource("Resource_6jwab")
[node name="BGSprite2D" parent="Ground" index="2"] [node name="BGSprite2D" parent="Ground" index="2"]
position = Vector2(23, -118) position = Vector2(23, -118)
@ -78,7 +69,7 @@ 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, 42)
texture = ExtResource("9_x837o") texture = ExtResource("9_x837o")
editor_filter = "c01" title_filter = "c01"
note_key = "c01_院长书桌" note_key = "c01_院长书桌"
[node name="Sign" parent="Ground/DeployLayer/桌椅" index="1"] [node name="Sign" parent="Ground/DeployLayer/桌椅" index="1"]
@ -91,13 +82,14 @@ 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, -28)
texture = ExtResource("11_6gq1s") texture = ExtResource("11_6gq1s")
editor_filter = "c01" title_filter = "notes"
note_key = "notes_挂画"
[node name="Sign" parent="Ground/DeployLayer/画框" index="1"] [node name="Sign" parent="Ground/DeployLayer/画框" index="1"]
offset_left = 6.0 offset_left = 3.0
offset_top = -1.0 offset_top = -7.0
offset_right = 89.0 offset_right = 86.0
offset_bottom = 79.0 offset_bottom = 73.0
[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)
@ -106,7 +98,7 @@ shape = SubResource("RectangleShape2D_6bim4")
[node name="鸡毛掸子" parent="Ground/DeployLayer" index="7" instance=ExtResource("10_18v0g")] [node name="鸡毛掸子" parent="Ground/DeployLayer" index="7" instance=ExtResource("10_18v0g")]
position = Vector2(269, 20) position = Vector2(269, 20)
texture = ExtResource("12_jtglg") texture = ExtResource("12_jtglg")
editor_filter = "c01" title_filter = "c01"
note_key = "c01_鸡毛掸子" note_key = "c01_鸡毛掸子"
[node name="Area2D" parent="Ground/DeployLayer/鸡毛掸子" index="3"] [node name="Area2D" parent="Ground/DeployLayer/鸡毛掸子" index="3"]
@ -116,24 +108,37 @@ position = Vector2(-7, 0)
shape = SubResource("RectangleShape2D_dq2na") shape = SubResource("RectangleShape2D_dq2na")
[node name="Interactable" parent="Ground/DeployLayer" index="8" instance=ExtResource("14_lq1ou")] [node name="Interactable" parent="Ground/DeployLayer" index="8" instance=ExtResource("14_lq1ou")]
position = Vector2(210, 36) position = Vector2(207, 30)
one_shot = false one_shot = false
prop_key = "prop_令牌" 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_40ng7")
[node name="PointLight2D" type="PointLight2D" parent="Ground/AmbientLayer" index="0"] [node name="PointLight" type="PointLight2D" parent="Ground/AmbientLayer" index="0"]
visible = false visible = false
position = Vector2(283, 0) position = Vector2(283, 0)
texture = ExtResource("15_6p040") texture = ExtResource("16_qh7fg")
[node name="PointLight窗" type="PointLight2D" parent="Ground/AmbientLayer" index="1"]
position = Vector2(283, 0)
energy = 1.4
texture = ExtResource("17_qqw2v")
texture_scale = 0.33 texture_scale = 0.33
height = 40.0 height = 50.0
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
position = Vector2(22, 49) position = Vector2(22, 49)
texture = ExtResource("3_vmr0f") texture = ExtResource("3_vmr0f")
[node name="HdLayer" parent="Ground/SubViewportContainer/SubViewport" index="0"]
layer = -1
[node name="DirectionalLight2D" parent="Ground" index="7"]
rotation = -0.000622023
energy = 0.3
blend_mode = 1
[node name="参考" type="Sprite2D" parent="Ground"] [node name="参考" type="Sprite2D" parent="Ground"]
visible = false visible = false
modulate = Color(1, 1, 1, 0.219608) modulate = Color(1, 1, 1, 0.219608)
@ -146,3 +151,4 @@ texture = ExtResource("3_7u4bh")
[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"]

View File

@ -1,25 +1,15 @@
[gd_scene load_steps=7 format=3 uid="uid://bbs7yy5aofw1v"] [gd_scene load_steps=5 format=3 uid="uid://bbs7yy5aofw1v"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_gdcov"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_gdcov"]
[ext_resource type="Script" path="res://config/deploy/scene_config.gd" id="2_j6mie"]
[ext_resource type="Texture2D" uid="uid://kc4726andgy2" path="res://asset/art/scene/c02/s01_街道/bg_公寓入口.png" id="2_ni1a4"] [ext_resource type="Texture2D" uid="uid://kc4726andgy2" path="res://asset/art/scene/c02/s01_街道/bg_公寓入口.png" id="2_ni1a4"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6lnxd"] [ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6lnxd"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_vgxa0"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_vgxa0"]
[sub_resource type="Resource" id="Resource_p1xa1"]
resource_local_to_scene = true
script = ExtResource("2_j6mie")
player_y_fixed = true
player_y = 45
footstep_type = "concrete"
bgm = ""
[node name="S01" type="Node2D"] [node name="S01" type="Node2D"]
[node name="Ground" parent="." instance=ExtResource("1_gdcov")] [node name="Ground" parent="." instance=ExtResource("1_gdcov")]
scene_config = SubResource("Resource_p1xa1")
[node name="BGSprite2D" parent="Ground" index="1"] [node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("2_ni1a4") texture = ExtResource("2_ni1a4")
[node name="portal_left" parent="Ground/DeployLayer" index="0"] [node name="portal_left" parent="Ground/DeployLayer" index="0"]
@ -27,7 +17,6 @@ position = Vector2(78, 27)
[node name="portal_right" parent="Ground/DeployLayer" index="1"] [node name="portal_right" parent="Ground/DeployLayer" index="1"]
position = Vector2(392, 2) position = Vector2(392, 2)
portal_name = "right"
target_scene = "c02_s02" target_scene = "c02_s02"
target_portal = "left" target_portal = "left"

View File

@ -1,7 +1,6 @@
[gd_scene load_steps=15 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://config/deploy/scene_config.gd" id="2_757mj"]
[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="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"]
@ -12,16 +11,9 @@
[ext_resource type="Texture2D" uid="uid://dtk3c3uqhn8ue" path="res://asset/art/scene/c01/s04_旧版序章/e_轿车.png" id="11_x0h3x"] [ext_resource type="Texture2D" uid="uid://dtk3c3uqhn8ue" path="res://asset/art/scene/c01/s04_旧版序章/e_轿车.png" id="11_x0h3x"]
[ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/local_inspectable.tscn" id="12_0fckv"] [ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/local_inspectable.tscn" id="12_0fckv"]
[sub_resource type="Resource" id="Resource_hd50m"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_vc6i4"]
resource_local_to_scene = true resource_local_to_scene = true
script = ExtResource("2_757mj") size = Vector2(35, 70)
player_y_fixed = true
player_y = 45
footstep_type = "concrete"
bgm = ""
[sub_resource type="RectangleShape2D" id="RectangleShape2D_0xrg2"]
size = Vector2(40, 150)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_3qhvr"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_3qhvr"]
resource_local_to_scene = true resource_local_to_scene = true
@ -30,22 +22,17 @@ size = Vector2(35, 70)
[node name="S02" type="Node2D"] [node name="S02" type="Node2D"]
[node name="Ground" parent="." instance=ExtResource("1_wrr6r")] [node name="Ground" parent="." instance=ExtResource("1_wrr6r")]
scene_config = SubResource("Resource_hd50m")
[node name="BGSprite2D" parent="Ground" index="1"] [node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("2_cn1s8") texture = ExtResource("2_cn1s8")
[node name="PortalLeft" parent="Ground/DeployLayer" index="0"] [node name="portal_right" parent="Ground/DeployLayer" index="1"]
position = Vector2(24, 1) position = Vector2(678, 6)
[node name="PortalRight" parent="Ground/DeployLayer" index="1"]
position = Vector2(676, 3)
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="几张卫生宣传画" parent="Ground/DeployLayer" index="2" instance=ExtResource("3_fy0o1")]
position = Vector2(275, -30) position = Vector2(275, -30)
editor_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="3" instance=ExtResource("12_0fckv")]
@ -54,19 +41,21 @@ 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="4" instance=ExtResource("5_nhtbp")]
position = Vector2(601, 44) position = Vector2(599, 44)
texture = ExtResource("7_xsghn") texture = ExtResource("7_xsghn")
flip_h = true flip_h = true
[node name="StaticBody2D" type="StaticBody2D" parent="Ground/DeployLayer/纸人"] [node name="Sign" parent="Ground/DeployLayer/纸人" index="1"]
collision_layer = 0 offset_left = -63.5
collision_mask = 0 offset_top = -114.0
offset_right = -63.5
offset_bottom = -34.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/纸人/StaticBody2D"] [node name="CollisionShape2D" parent="Ground/DeployLayer/纸人/Area2D" index="0"]
shape = SubResource("RectangleShape2D_0xrg2") shape = SubResource("RectangleShape2D_vc6i4")
[node name="Ambush" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_70vqn")] [node name="Ambush" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_70vqn")]
position = Vector2(502, 56) position = Vector2(502, 54)
hook_animation = null hook_animation = null
lock_player_on_playing_dialogue = null lock_player_on_playing_dialogue = null
hook_dialogue_res = null hook_dialogue_res = null
@ -78,10 +67,10 @@ texture = ExtResource("11_x0h3x")
sprite_ref = NodePath("../../SubViewportContainer/SubViewport/HdLayer/car") sprite_ref = NodePath("../../SubViewportContainer/SubViewport/HdLayer/car")
[node name="Sign" parent="Ground/DeployLayer/HdEntity" index="1"] [node name="Sign" parent="Ground/DeployLayer/HdEntity" index="1"]
offset_left = 1.0 offset_left = -9.0
offset_top = -28.0 offset_top = -32.0
offset_right = 84.0 offset_right = 74.0
offset_bottom = 52.0 offset_bottom = 48.0
[node name="CollisionShape2D" parent="Ground/DeployLayer/HdEntity/Area2D" index="0"] [node name="CollisionShape2D" parent="Ground/DeployLayer/HdEntity/Area2D" index="0"]
shape = SubResource("RectangleShape2D_3qhvr") shape = SubResource("RectangleShape2D_3qhvr")
@ -90,4 +79,5 @@ shape = SubResource("RectangleShape2D_3qhvr")
texture = null texture = null
[editable path="Ground"] [editable path="Ground"]
[editable path="Ground/DeployLayer/纸人"]
[editable path="Ground/DeployLayer/HdEntity"] [editable path="Ground/DeployLayer/HdEntity"]

View File

@ -1,8 +1,7 @@
[gd_scene load_steps=15 format=3 uid="uid://djc2uaefhmu7"] [gd_scene load_steps=13 format=3 uid="uid://djc2uaefhmu7"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_lheeb"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_lheeb"]
[ext_resource type="PackedScene" uid="uid://0sofmhrl358m" path="res://scene/entity/npc.tscn" id="2_r5smg"] [ext_resource type="PackedScene" uid="uid://0sofmhrl358m" path="res://scene/entity/npc.tscn" id="2_r5smg"]
[ext_resource type="Script" path="res://config/deploy/scene_config.gd" id="2_uifea"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6x7xl"] [ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6x7xl"]
[ext_resource type="Texture2D" uid="uid://bb3f72fla7mvs" path="res://asset/art/scene/c02/s03_院子切换/bg_院子1楼(黄昏无人).png" id="3_78bcp"] [ext_resource type="Texture2D" uid="uid://bb3f72fla7mvs" path="res://asset/art/scene/c02/s03_院子切换/bg_院子1楼(黄昏无人).png" id="3_78bcp"]
[ext_resource type="Texture2D" uid="uid://dqsl8rcues8hs" path="res://asset/art/scene/c02/s03_院子切换/n_院子1楼(黄昏无人).png" id="4_nef6w"] [ext_resource type="Texture2D" uid="uid://dqsl8rcues8hs" path="res://asset/art/scene/c02/s03_院子切换/n_院子1楼(黄昏无人).png" id="4_nef6w"]
@ -12,14 +11,6 @@
[ext_resource type="PackedScene" uid="uid://svvlohuicvhf" path="res://scene/entity/ambient/light.tscn" id="10_uxbu3"] [ext_resource type="PackedScene" uid="uid://svvlohuicvhf" path="res://scene/entity/ambient/light.tscn" id="10_uxbu3"]
[ext_resource type="PackedScene" uid="uid://b8ncf4d0jda8r" path="res://scene/entity/partical/particals_ash.tscn" id="13_kq517"] [ext_resource type="PackedScene" uid="uid://b8ncf4d0jda8r" path="res://scene/entity/partical/particals_ash.tscn" id="13_kq517"]
[sub_resource type="Resource" id="Resource_vdo00"]
resource_local_to_scene = true
script = ExtResource("2_uifea")
player_y_fixed = true
player_y = 45
footstep_type = "concrete"
bgm = ""
[sub_resource type="CanvasTexture" id="CanvasTexture_41q0k"] [sub_resource type="CanvasTexture" id="CanvasTexture_41q0k"]
diffuse_texture = ExtResource("3_78bcp") diffuse_texture = ExtResource("3_78bcp")
normal_texture = ExtResource("4_nef6w") normal_texture = ExtResource("4_nef6w")
@ -31,26 +22,27 @@ size = Vector2(40, 70)
[node name="S03" type="Node2D"] [node name="S03" type="Node2D"]
[node name="Ground" parent="." instance=ExtResource("1_lheeb")] [node name="Ground" parent="." instance=ExtResource("1_lheeb")]
scene_config = SubResource("Resource_vdo00")
[node name="BGSprite2D" parent="Ground" index="1"] [node name="BGSprite2D" parent="Ground" index="2"]
texture = SubResource("CanvasTexture_41q0k") texture = SubResource("CanvasTexture_41q0k")
[node name="PortalLeft" parent="Ground/DeployLayer" index="0"] [node name="portal_left" parent="Ground/DeployLayer" index="0"]
position = Vector2(25, 3)
target_scene = "c02_s02" target_scene = "c02_s02"
target_portal = "right" target_portal = "right"
[node name="PortalRight" parent="Ground/DeployLayer" index="1"] [node name="portal_right" parent="Ground/DeployLayer" index="1"]
visible = false position = Vector2(629, 2)
[node name="Npc" parent="Ground/DeployLayer" index="2" instance=ExtResource("2_r5smg")] [node name="Npc" parent="Ground/DeployLayer" index="2" instance=ExtResource("2_r5smg")]
position = Vector2(465, 23) position = Vector2(465, 23)
frame_progress = 0.94813 frame_progress = 0.663565
character_name = "张胖子" character_name = "张胖子"
dialogue_title = "张胖子_01" dialogue_title = "张胖子_01"
[node name="Note" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_6x7xl")] [node name="Note" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_6x7xl")]
position = Vector2(268, -36) position = Vector2(268, -36)
note_key = "c02_老鼠洞2"
[node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_gg4jv")] [node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_gg4jv")]
position = Vector2(343, 33) position = Vector2(343, 33)
@ -63,7 +55,8 @@ shape = SubResource("RectangleShape2D_ec3g1")
[node name="Interactable" parent="Ground/DeployLayer" index="5" instance=ExtResource("8_vdelk")] [node name="Interactable" parent="Ground/DeployLayer" index="5" instance=ExtResource("8_vdelk")]
position = Vector2(1072, 22) position = Vector2(1072, 22)
collision_mask = 1 unmatched_sign_texture = null
matched_sign_texture = null
[node name="灯笼" parent="Ground/AmbientLayer" index="0" instance=ExtResource("10_uxbu3")] [node name="灯笼" parent="Ground/AmbientLayer" index="0" instance=ExtResource("10_uxbu3")]
position = Vector2(845, -25) position = Vector2(845, -25)
@ -85,7 +78,7 @@ texture = ExtResource("7_icddm")
position = Vector2(-12, -143) position = Vector2(-12, -143)
scale = Vector2(1.08, 1.08) scale = Vector2(1.08, 1.08)
[node name="DirectionalLight2D" parent="Ground" index="6"] [node name="DirectionalLight2D" parent="Ground" index="7"]
color = Color(0.368627, 0.447059, 0.882353, 1) color = Color(0.368627, 0.447059, 0.882353, 1)
[editable path="Ground"] [editable path="Ground"]

View File

@ -1,6 +1,8 @@
@tool @tool
class_name PropHud extends Control class_name PropHud extends Control
signal current_item_changed(prop_key: String)
@export_group("DebugItem") @export_group("DebugItem")
@export var enable_item := false: @export var enable_item := false:
set(value): set(value):
@ -9,17 +11,26 @@ class_name PropHud extends Control
enable_prop_item(item_key) enable_prop_item(item_key)
@export var item_key: String @export var item_key: String
@export_group("Inventory") @export_group("Inventory")
@export var inventory: PropInventory @export var inventory: PropInventory:
set(value):
inventory = value
if inventory:
inventory.current_item_changed.connect(current_item_changed.emit)
@export_group("UI-UX") @export_group("UI-UX")
@export var display_time := 2.5 # 不包含渐入渐出(约 0.6s)的时长 @export var display_time := 2.5 # 不包含渐入渐出(约 0.6s)的时长
@export var locked := false @export var locked := false:
set(value):
locked = value
if value:
selected = false
@export var selected := false: @export var selected := false:
set(value): set(value):
selected = value selected = value
if is_node_ready(): if is_node_ready():
%Mark.visible = value %Mark.visible = value
mark.modulate.a = 1.0
@onready var sfx = %Sfx as Sfx @onready var sfx_click = %SfxClick as Sfx
@onready var left_btn = %LeftButton as TextureButton @onready var left_btn = %LeftButton as TextureButton
@onready var right_btn = %RightButton as TextureButton @onready var right_btn = %RightButton as TextureButton
@onready var panel = %HudPanel as TextureButton @onready var panel = %HudPanel as TextureButton
@ -31,7 +42,7 @@ class_name PropHud extends Control
var items_dict := {} var items_dict := {}
# 从配置文件加载 prop items # 从配置文件加载 prop items
var item_config_res = preload("res://asset/dialogue/item_description.dialogue") var item_config_res = preload("res://asset/dialogue/item_description.dialogue")
var texture_path_prefix = "res://asset/art/prop/" var path_prefix = "res://asset/art/prop/"
var cached_inventory_textures := {} var cached_inventory_textures := {}
var listen_mouse = false var listen_mouse = false
@ -78,15 +89,21 @@ func _load_items():
var current_line = item_config_res.lines[id] var current_line = item_config_res.lines[id]
while current_line: while current_line:
if current_line.has("tags") and current_line.has("translation_key"): if current_line.has("tags") and current_line.has("translation_key"):
var wrapped := "texture=" var wrapped_texture := "texture="
var wrapped_inspect := "inspect="
var texture_path = "" var texture_path = ""
var inspect_path = ""
for t in current_line.tags: for t in current_line.tags:
if t.begins_with(wrapped): if t.begins_with(wrapped_texture):
texture_path = t.replace(wrapped, "").strip_edges() texture_path = t.replace(wrapped_texture, "").strip_edges()
break elif t.begins_with(wrapped_inspect):
inspect_path = t.replace(wrapped_inspect, "").strip_edges()
var item = PropItem.new() var item = PropItem.new()
item.key = current_line.translation_key item.key = current_line.translation_key
item.texture_path = texture_path_prefix + texture_path if texture_path:
item.texture_path = path_prefix + texture_path
if inspect_path:
item.inspect_path = path_prefix + inspect_path
items_dict[item.key] = item items_dict[item.key] = item
if not current_line.has("next_id") or current_line.next_id == "end": if not current_line.has("next_id") or current_line.next_id == "end":
break break
@ -109,7 +126,10 @@ func _load_texture_cache() -> void:
if not key in items_dict: if not key in items_dict:
inventory.enabled_items.erase(key) inventory.enabled_items.erase(key)
continue continue
var texture = load(items_dict[key].texture_path) as Texture2D var path = items_dict[key].texture_path
if not path:
continue
var texture = load(path) as Texture2D
if texture: if texture:
cached_inventory_textures[key] = texture cached_inventory_textures[key] = texture
# wrap index # wrap index
@ -135,7 +155,9 @@ func _update_prop_display_with_texture():
func on_left_pressed() -> void: func on_left_pressed() -> void:
sfx.play() if locked:
return
sfx_click.play()
_mouse_moved_on_listening() _mouse_moved_on_listening()
if inventory.index_wrap_add(-1): if inventory.index_wrap_add(-1):
selected = false selected = false
@ -144,7 +166,9 @@ func on_left_pressed() -> void:
func on_right_pressed() -> void: func on_right_pressed() -> void:
sfx.play() if locked:
return
sfx_click.play()
_mouse_moved_on_listening() _mouse_moved_on_listening()
if inventory.index_wrap_add(1): if inventory.index_wrap_add(1):
selected = false selected = false
@ -165,7 +189,9 @@ func _tween_container(left_to_right := true) -> void:
func _on_panel_pressed() -> void: func _on_panel_pressed() -> void:
sfx.play() if locked:
return
sfx_click.play()
if not selected: if not selected:
focus_mode = FOCUS_ALL focus_mode = FOCUS_ALL
grab_focus() grab_focus()
@ -174,6 +200,8 @@ func _on_panel_pressed() -> void:
func _on_mouse_entered() -> void: func _on_mouse_entered() -> void:
if locked:
return
listen_mouse = true listen_mouse = true
_mouse_moved_on_listening() _mouse_moved_on_listening()
@ -256,6 +284,16 @@ func enable_prop_item(prop_key: String) -> void:
_update_prop_display_with_texture() _update_prop_display_with_texture()
# save to archive immediately # save to archive immediately
ArchiveManager.save_all() ArchiveManager.save_all()
var inspector = SceneManager.get_inspector()
if inspector:
var texture = load(items_dict[prop_key].inspect_path) as Texture2D
inspector.pop_prop_inspection(texture)
var prop_title = tr(prop_key)
var obtain_str = tr("ui_获得")
var text = "~ " + prop_key + "\n" + obtain_str + ": " + prop_title
text += "[#item][ID:" + prop_title + "]\n=> END"
var prop_res = DialogueManager.create_resource_from_text(text)
DialogueManager.show_dialogue_balloon(prop_res, prop_key)
func disable_prop_item(prop_key: String) -> void: func disable_prop_item(prop_key: String) -> void:
@ -266,3 +304,44 @@ func disable_prop_item(prop_key: String) -> void:
_update_prop_display_with_texture() _update_prop_display_with_texture()
# save to archive immediately # save to archive immediately
ArchiveManager.save_all() ArchiveManager.save_all()
var shake_tween
# 使用无效道具,抖动提示
func on_toggle_invalid_prop():
if GlobalConfig.DEBUG:
print("使用无效道具. current prop:", inventory.current_item_key())
if not inventory or not inventory.current_item_key():
return
if shake_tween:
shake_tween.kill()
# 抖动效果,逐渐减弱
shake_tween = create_tween()
var fps := 15.0
var duration := 0.8
var delta := 12.0
var origin_pos = Vector2.ZERO
var count = int(duration * fps)
var delta_t = 1.0 / fps
prop.modulate = Color(1.0, 0.6, 0.6, 1.0)
for i in range(count):
var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta)) * exp(-i)
shake_tween.tween_property(prop, "position", origin_pos + offset, delta_t).set_trans(
Tween.TRANS_CUBIC
)
shake_tween.tween_callback(_reset_prop_modulate)
func _reset_prop_modulate():
prop.modulate = Color(1.0, 1.0, 1.0, 1.0)
func on_toggle_valid_prop():
if GlobalConfig.DEBUG:
print("使用有效道具. current prop:", inventory.current_item_key())
# 展示 mark
if not selected:
focus_mode = FOCUS_ALL
grab_focus()
selected = true
_mouse_moved_on_listening()

View File

@ -31,7 +31,7 @@ mouse_filter = 0
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
layout_mode = 2 layout_mode = 2
[node name="Sfx" parent="VBoxContainer/HBoxContainer" instance=ExtResource("2_g6c03")] [node name="SfxClick" parent="VBoxContainer/HBoxContainer" instance=ExtResource("2_g6c03")]
unique_name_in_owner = true unique_name_in_owner = true
[node name="LeftMargin" type="MarginContainer" parent="VBoxContainer/HBoxContainer"] [node name="LeftMargin" type="MarginContainer" parent="VBoxContainer/HBoxContainer"]

View File

@ -1,7 +1,14 @@
class_name PropInventory extends Resource class_name PropInventory extends Resource
signal current_item_changed(prop_key: String)
@export var enabled_items := [] as Array[String] @export var enabled_items := [] as Array[String]
@export var current_index := 0 @export var current_index := 0:
set(val):
if current_index != val:
val = wrapi(val, 0, enabled_items.size())
current_index = val
current_item_changed.emit(enabled_items[current_index])
func current_item_key(): func current_item_key():
@ -13,7 +20,8 @@ func current_item_key():
func enable_item(prop_key: String) -> void: func enable_item(prop_key: String) -> void:
if not enabled_items.has(prop_key): if not enabled_items.has(prop_key):
enabled_items.append(prop_key) enabled_items.append(prop_key)
# emit_changed() # 新增后直接选中
current_index = enabled_items.find(prop_key)
func disable_item(prop_key: String) -> void: func disable_item(prop_key: String) -> void:
@ -25,7 +33,6 @@ func disable_item(prop_key: String) -> void:
# return true if the index changed # return true if the index changed
func index_wrap_add(delta: int) -> bool: func index_wrap_add(delta: int) -> bool:
# auto wrapped in setter
current_index += delta current_index += delta
current_index = wrapi(current_index, 0, enabled_items.size())
# emit_changed()
return not enabled_items.is_empty() return not enabled_items.is_empty()

View File

@ -3,3 +3,4 @@ class_name PropItem extends Resource
# unique name # unique name
@export var key := "" @export var key := ""
@export_file("*.png") var texture_path := "" @export_file("*.png") var texture_path := ""
@export_file("*.png") var inspect_path := ""

View File

@ -74,6 +74,7 @@ metadata/_edit_use_anchors_ = true
[node name="PropHUD" parent="UILayer" instance=ExtResource("4_t7gb2")] [node name="PropHUD" parent="UILayer" instance=ExtResource("4_t7gb2")]
scale = Vector2(0.24, 0.24) scale = Vector2(0.24, 0.24)
item_key = "prop_令牌"
display_time = 1.5 display_time = 1.5
metadata/_edit_use_anchors_ = true metadata/_edit_use_anchors_ = true

View File

@ -1,7 +1,7 @@
@tool @tool
class_name PropInspector extends CanvasLayer class_name PropInspector extends CanvasLayer
enum { STATUS_HIDDEN, STATUS_INSPECTING_COVER, STATUS_INSPECTING_NOTES } enum { STATUS_HIDDEN, STATUS_INSPECTING_PROP, STATUS_INSPECTING_COVER, STATUS_INSPECTING_NOTES }
# must be connected to # must be connected to
signal quit signal quit
@ -16,7 +16,7 @@ var texture_cover: Texture2D
var texture_notes: Texture2D var texture_notes: Texture2D
var status := STATUS_HIDDEN var status := STATUS_HIDDEN
var blinking_tween : Tween var blinking_tween: Tween
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
@ -62,7 +62,9 @@ func _blink_label(init := true):
blinking_tween.tween_callback(_blink_label.bind(true)) blinking_tween.tween_callback(_blink_label.bind(true))
func pop_inspection(cover_texture, notes_texture, inspection_note): func pop_standard_inspection(cover_texture, notes_texture, inspection_note):
if status != STATUS_HIDDEN:
_hide()
status = STATUS_INSPECTING_COVER status = STATUS_INSPECTING_COVER
visible = true visible = true
texture_rect.texture = cover_texture texture_rect.texture = cover_texture
@ -72,18 +74,38 @@ func pop_inspection(cover_texture, notes_texture, inspection_note):
SceneManager.freeze_player(0) SceneManager.freeze_player(0)
var tween = create_tween() var tween = create_tween()
tween.tween_property(texture_rect, "modulate:a", 1.0, 0.15) tween.tween_property(texture_rect, "modulate:a", 1.0, 0.15)
tip_label.text = tip_cover
_blink_label() _blink_label()
func pop_prop_inspection(cover_texture):
if status != STATUS_HIDDEN:
_hide()
if not cover_texture:
push_error("PropInspector: cover_texture is not set")
return
status = STATUS_INSPECTING_PROP
visible = true
texture_rect.texture = cover_texture
texture_cover = cover_texture
texture_notes = null
content_label.text = ""
tip_label.text = ""
SceneManager.freeze_player(0)
var tween = create_tween()
tween.tween_property(texture_rect, "modulate:a", 1.0, 0.15)
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
if status == STATUS_HIDDEN: if status == STATUS_HIDDEN:
return return
if event.is_action_pressed("cancel"): if event.is_action_pressed("cancel"):
quit.emit()
_hide()
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
_hide()
quit.emit()
if event.is_action_pressed("interact"): if event.is_action_pressed("interact"):
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
# STATUS_INSPECTING_COVER 与 STATUS_INSPECTING_NOTES 之间互相切换
if status == STATUS_INSPECTING_COVER: if status == STATUS_INSPECTING_COVER:
# inspect notes # inspect notes
status = STATUS_INSPECTING_NOTES status = STATUS_INSPECTING_NOTES
@ -96,3 +118,7 @@ func _unhandled_input(event: InputEvent) -> void:
texture_rect.texture = texture_cover texture_rect.texture = texture_cover
tip_label.text = tip_cover tip_label.text = tip_cover
create_tween().tween_property(content_label, "modulate:a", 0.0, 0.2) create_tween().tween_property(content_label, "modulate:a", 0.0, 0.2)
# STATUS_INSPECTING_PROP 直接退出
elif status == STATUS_INSPECTING_PROP:
_hide()
quit.emit()