实现完整的道具交互 UX 效果
BIN
asset/art/animation/c01_信碎片_falling/1.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/10.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/2.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/3.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/4.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/5.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/6.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/7.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/8.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
asset/art/animation/c01_信碎片_falling/9.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 123 KiB |
BIN
asset/art/scene/c01/s05_院长房间/l_墙.png
Executable file
After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 143 KiB |
BIN
asset/art/scene/c01/s05_院长房间/l_窗户光源.png
Normal file
After Width: | Height: | Size: 186 KiB |
BIN
asset/art/ui/action_mark/探索空心ui.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
asset/art/ui/互动提示符/ui 像素版_纯白.png
Normal file
After Width: | Height: | Size: 11 KiB |
@ -1,16 +1,34 @@
|
||||
keys,zh_Hans,en,_character,_notes,_tags
|
||||
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_阅读,阅读,Read,,,
|
||||
ui_收起,收起,Hold,,,
|
||||
prop_令牌,令牌,,,,[#texture=c01/令牌物品.png]
|
||||
prop_装有灵魂的令牌,装有灵魂的令牌,,,,[#texture=c01/装有灵魂的令牌物品.png]
|
||||
prop_小猫玩具的脑袋,小猫玩具的脑袋,Catty's Head,,,[#texture=c02/小猫玩具脑袋物品.png]
|
||||
prop_绳子,绳子,Rope,,,[#texture=c02/绳子物品.png]
|
||||
prop_1012钥匙,1012钥匙,1012 Key,,,[#texture=c02/1012钥匙物品.png]
|
||||
prop_老虎钳,老虎钳,,,,[#texture=c02/老虎钳物品.png]
|
||||
prop_3014旋转锁钥匙,3014旋转锁钥匙,,,,[#texture=c02/3014旋转锁钥匙物品.png]
|
||||
prop_小猫玩具完整,小猫玩具,,,,[#texture=c02/小猫玩具完整物品.png]
|
||||
prop_空手,空手,,,,
|
||||
prop_令牌,令牌,,,,[#texture=c01/令牌物品.png][#inspect=c01/令牌.png]
|
||||
prop_装有灵魂的令牌,装有灵魂的令牌,,,,[#texture=c01/装有灵魂的令牌物品.png][#inspect=c01/装有灵魂的令牌.png]
|
||||
prop_小猫玩具的脑袋,小猫玩具的脑袋,Catty's Head,,,[#texture=c02/小猫玩具脑袋物品.png][#inspect=c02/小猫玩具脑袋.png]
|
||||
prop_绳子,绳子,Rope,,,[#texture=c02/绳子物品.png][#inspect=c02/绳子.png]
|
||||
prop_1012钥匙,1012钥匙,1012 Key,,,[#texture=c02/1012钥匙物品.png][#inspect=c02/1012钥匙.png]
|
||||
prop_老虎钳,老虎钳,,,,[#texture=c02/老虎钳物品.png][#inspect=c02/老虎钳.png]
|
||||
prop_3014旋转锁钥匙,3014旋转锁钥匙,,,,[#texture=c02/3014旋转锁钥匙物品.png][#inspect=c02/3014旋转锁钥匙.png]
|
||||
prop_小猫玩具完整,小猫玩具,,,,[#texture=c02/小猫玩具完整物品.png][#inspect=c02/小猫玩具完整.png]
|
||||
notes_纸条,纸条,,,,
|
||||
notes_锁住了,锁住了,,,,
|
||||
notes_打不开,打不开,,,,
|
||||
@ -24,12 +42,12 @@ c01_鸡毛掸子,这是鸡毛掸子吗?,,,,
|
||||
c01_院长书桌,书桌上好像有本书,,,,
|
||||
c01_院长座钟,唔...下午一点了,,,,
|
||||
c02_绳子剪刀,绳子和剪刀,,,,
|
||||
c02_寻人启事1,似乎是一张寻人启事,,,,
|
||||
c02_寻人启事2,脸的部分被撕掉了,看不清,,,,
|
||||
c02_寻人启事,"似乎是一张寻人启事
|
||||
脸的部分被撕掉了,看不清",,,,
|
||||
c02_玩具缺脑袋,这个玩具缺了个脑袋,,,,
|
||||
c02_卫生宣传画,几张卫生宣传画,,,,
|
||||
c02_老鼠洞1,一个老鼠洞,,,,
|
||||
c02_老鼠洞2,在这种楼里挺常见的,,,,
|
||||
c02_老鼠洞,"一个老鼠洞
|
||||
在这种楼里挺常见的",,,,
|
||||
c02_十几年前的报纸,十几年前的报纸,,,,
|
||||
c02_又是寻人启示,又是那张寻人启示,,,,
|
||||
c02_墙上的海报被撕掉了,墙上的海报被撕掉了,,,,
|
||||
@ -63,17 +81,5 @@ c02_锁开了,锁开了,,,,
|
||||
c02_口袋里有东西,口袋里有东西,,,,
|
||||
c02_雾太大,雾太大了,看不清路,,,,
|
||||
c02_八音盒,是个八音盒,,,,
|
||||
=>en,=>en,,,,
|
||||
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,5 +1,6 @@
|
||||
# UI
|
||||
~ UI
|
||||
获得 [ID:ui_获得]
|
||||
退出 [ID:ui_退出]
|
||||
阅读 [ID:ui_阅读]
|
||||
收起 [ID:ui_收起]
|
||||
@ -7,273 +8,73 @@
|
||||
|
||||
~ PropItems
|
||||
# texture 路径从 "res://asset/art/prop/" 之后算起
|
||||
空手 [ID:prop_空手]
|
||||
# c01
|
||||
令牌 [#texture=c01/令牌物品.png] [ID:prop_令牌]
|
||||
装有灵魂的令牌 [#texture=c01/装有灵魂的令牌物品.png] [ID:prop_装有灵魂的令牌]
|
||||
令牌 [#texture=c01/令牌物品.png][#inspect=c01/令牌.png] [ID:prop_令牌]
|
||||
装有灵魂的令牌 [#texture=c01/装有灵魂的令牌物品.png][#inspect=c01/装有灵魂的令牌.png] [ID:prop_装有灵魂的令牌]
|
||||
# c02
|
||||
小猫玩具的脑袋 [#texture=c02/小猫玩具脑袋物品.png] [ID:prop_小猫玩具的脑袋]
|
||||
绳子 [#texture=c02/绳子物品.png] [ID:prop_绳子]
|
||||
1012钥匙 [#texture=c02/1012钥匙物品.png] [ID:prop_1012钥匙]
|
||||
老虎钳 [#texture=c02/老虎钳物品.png] [ID:prop_老虎钳]
|
||||
3014旋转锁钥匙 [#texture=c02/3014旋转锁钥匙物品.png] [ID:prop_3014旋转锁钥匙]
|
||||
小猫玩具 [#texture=c02/小猫玩具完整物品.png] [ID:prop_小猫玩具完整]
|
||||
小猫玩具的脑袋 [#texture=c02/小猫玩具脑袋物品.png][#inspect=c02/小猫玩具脑袋.png] [ID:prop_小猫玩具的脑袋]
|
||||
绳子 [#texture=c02/绳子物品.png][#inspect=c02/绳子.png] [ID:prop_绳子]
|
||||
1012钥匙 [#texture=c02/1012钥匙物品.png][#inspect=c02/1012钥匙.png] [ID:prop_1012钥匙]
|
||||
老虎钳 [#texture=c02/老虎钳物品.png][#inspect=c02/老虎钳.png] [ID:prop_老虎钳]
|
||||
3014旋转锁钥匙 [#texture=c02/3014旋转锁钥匙物品.png][#inspect=c02/3014旋转锁钥匙.png] [ID:prop_3014旋转锁钥匙]
|
||||
小猫玩具 [#texture=c02/小猫玩具完整物品.png][#inspect=c02/小猫玩具完整.png] [ID:prop_小猫玩具完整]
|
||||
=> END
|
||||
|
||||
# notes 通用
|
||||
~ notes_纸条
|
||||
~ Notes
|
||||
# 通用
|
||||
纸条 [ID:notes_纸条]
|
||||
=> END
|
||||
|
||||
~ notes_锁住了
|
||||
锁住了 [ID:notes_锁住了]
|
||||
=> END
|
||||
|
||||
~ notes_打不开
|
||||
打不开 [ID:notes_打不开]
|
||||
=> END
|
||||
|
||||
~ notes_干掉的血迹
|
||||
干掉的血迹 [ID:notes_干掉的血迹]
|
||||
=> END
|
||||
|
||||
~ notes_有什么东西
|
||||
有什么东西 [ID:notes_有什么东西]
|
||||
=> END
|
||||
|
||||
~ notes_无法触碰
|
||||
无法触碰 [ID:notes_无法触碰]
|
||||
=> END
|
||||
|
||||
~ notes_挂画
|
||||
挂画 [ID:notes_挂画]
|
||||
=> END
|
||||
|
||||
~ notes_相框
|
||||
相框 [ID:notes_相框]
|
||||
=> END
|
||||
|
||||
~ notes_寻人启事
|
||||
寻人启事 [ID:notes_寻人启事]
|
||||
=> END
|
||||
|
||||
# c01
|
||||
~ c01_鸡毛掸子
|
||||
这是鸡毛掸子吗? [ID:c01_鸡毛掸子]
|
||||
=> END
|
||||
|
||||
~ c01_院长书桌
|
||||
书桌上好像有本书 [ID:c01_院长书桌]
|
||||
=> END
|
||||
|
||||
~ c01_院长座钟
|
||||
唔...下午一点了 [ID:c01_院长座钟]
|
||||
=> END
|
||||
|
||||
# c02
|
||||
~ c02_绳子剪刀
|
||||
绳子和剪刀 [ID:c02_绳子剪刀]
|
||||
=> END
|
||||
|
||||
~ c02_寻人启事
|
||||
似乎是一张寻人启事 [ID:c02_寻人启事1]
|
||||
脸的部分被撕掉了,看不清 [ID:c02_寻人启事2]
|
||||
=> END
|
||||
|
||||
~ c02_玩具缺脑袋
|
||||
似乎是一张寻人启事\n脸的部分被撕掉了,看不清 [ID:c02_寻人启事]
|
||||
这个玩具缺了个脑袋 [ID:c02_玩具缺脑袋]
|
||||
=> END
|
||||
|
||||
~ c02_卫生宣传画
|
||||
几张卫生宣传画 [ID:c02_卫生宣传画]
|
||||
=> END
|
||||
|
||||
~ c02_老鼠洞
|
||||
一个老鼠洞 [ID:c02_老鼠洞1]
|
||||
在这种楼里挺常见的 [ID:c02_老鼠洞2]
|
||||
=> END
|
||||
|
||||
~ c02_十几年前的报纸
|
||||
一个老鼠洞\n在这种楼里挺常见的 [ID:c02_老鼠洞]
|
||||
十几年前的报纸 [ID:c02_十几年前的报纸]
|
||||
=> END
|
||||
|
||||
~ c02_又是寻人启示
|
||||
又是那张寻人启示 [ID:c02_又是寻人启示]
|
||||
=> END
|
||||
|
||||
~ c02_墙上的海报被撕掉了
|
||||
墙上的海报被撕掉了 [ID:c02_墙上的海报被撕掉了]
|
||||
=> END
|
||||
|
||||
~ c02_井臭
|
||||
井里有一股臭味 [ID:c02_井臭]
|
||||
=> END
|
||||
|
||||
~ c02_中药材
|
||||
车上放了一些中药材 [ID:c02_中药材]
|
||||
=> END
|
||||
|
||||
~ c02_排队
|
||||
排队的人堵住了上楼的路 [ID:c02_排队]
|
||||
=> END
|
||||
|
||||
~ c02_不要出去
|
||||
最好还是先不要出去 [ID:c02_不要出去]
|
||||
=> END
|
||||
|
||||
~ c02_太阳
|
||||
太阳快落山了 [ID:c02_太阳]
|
||||
=> END
|
||||
|
||||
~ c02_民国六年1015
|
||||
民国六年十月十五日 [ID:c02_民国六年1015]
|
||||
=> END
|
||||
|
||||
~ c02_一个洞
|
||||
一个洞,里面好像还有空间 [ID:c02_一个洞]
|
||||
=> END
|
||||
|
||||
~ c02_工具箱
|
||||
工具箱 [ID:c02_工具箱]
|
||||
=> END
|
||||
|
||||
~ c02_找到有用的东西
|
||||
应该能找到有用的东西 [ID:c02_找到有用的东西]
|
||||
=> END
|
||||
|
||||
~ c02_公寓告示
|
||||
公寓告示 [ID:c02_公寓告示]
|
||||
=> END
|
||||
|
||||
~ c02_通往里间的门
|
||||
通往里间的门 [ID:c02_通往里间的门]
|
||||
=> END
|
||||
|
||||
~ c02_花名册
|
||||
花名册 [ID:c02_花名册]
|
||||
=> END
|
||||
|
||||
~ c02_罪
|
||||
罪 [ID:c02_罪]
|
||||
=> END
|
||||
|
||||
~ c02_门上有什么东西
|
||||
门上有什么东西 [ID:c02_门上有什么东西]
|
||||
=> END
|
||||
|
||||
~ c02_奠
|
||||
奠 [ID:c02_奠]
|
||||
=> END
|
||||
|
||||
~ c02_寻夏小蝉
|
||||
失踪的小孩名叫夏小蝉 [ID:c02_寻夏小蝉]
|
||||
=> END
|
||||
|
||||
~ c02_小猫干尸
|
||||
小猫的尸体已经干了 [ID:c02_小猫干尸]
|
||||
=> END
|
||||
|
||||
~ c02_几块大洋
|
||||
几块大洋 [ID:c02_几块大洋]
|
||||
=> END
|
||||
|
||||
~ c02_死老鼠
|
||||
死掉的老鼠 [ID:c02_死老鼠]
|
||||
=> END
|
||||
|
||||
~ c02_石缝开花
|
||||
石缝里开了几束花 [ID:c02_石缝开花]
|
||||
=> END
|
||||
|
||||
~ c02_石壁空间
|
||||
石壁另一头好像还有空间 [ID:c02_石壁空间]
|
||||
=> END
|
||||
|
||||
~ c02_民国六年1221
|
||||
民国六年十二月二十一日 [ID:c02_民国六年1221]
|
||||
=> END
|
||||
|
||||
~ c02_患者感谢信
|
||||
一些患者的感谢信 [ID:c02_患者感谢信]
|
||||
=> END
|
||||
|
||||
~ c02_被撕掉的书
|
||||
一本被撕掉的书 [ID:c02_被撕掉的书]
|
||||
=> END
|
||||
|
||||
~ c02_里面有什么东西
|
||||
里面有什么东西 [ID:c02_里面有什么东西]
|
||||
=> END
|
||||
|
||||
~ c02_戏台上的诗
|
||||
戏台上面刻了一首诗 [ID:c02_戏台上的诗]
|
||||
=> END
|
||||
|
||||
~ c02_锁开了
|
||||
锁开了 [ID:c02_锁开了]
|
||||
=> END
|
||||
|
||||
~ c02_口袋里有东西
|
||||
口袋里有东西 [ID:c02_口袋里有东西]
|
||||
=> END
|
||||
|
||||
~ c02_雾太大
|
||||
雾太大了,看不清路 [ID:c02_雾太大]
|
||||
=> END
|
||||
|
||||
~ c02_八音盒
|
||||
是个八音盒 [ID:c02_八音盒]
|
||||
=>en
|
||||
|
||||
~ c02_祝女儿早日康复
|
||||
祝女儿早日康复 [ID:c02_祝女儿早日康复]
|
||||
=> END
|
||||
|
||||
~ 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
|
||||
|
@ -49,7 +49,8 @@
|
||||
"c02_黑手_捂屏幕": "",
|
||||
"c02_吕萍_爬行_idle_l": "",
|
||||
"c02_吕萍_爬行_idle_r": "",
|
||||
"c02_吕萍_爬行_left": ""
|
||||
"c02_吕萍_爬行_left": "",
|
||||
"c01_信碎片_falling": ""
|
||||
},
|
||||
"mirror_mapping": {
|
||||
"c00_吕萍_idle_left": "",
|
||||
@ -101,7 +102,8 @@
|
||||
"c02_黑手_捂屏幕": "",
|
||||
"c02_吕萍_爬行_idle_l": "",
|
||||
"c02_吕萍_爬行_idle_r": "",
|
||||
"c02_吕萍_爬行_left": ""
|
||||
"c02_吕萍_爬行_left": "",
|
||||
"c01_信碎片_falling": ""
|
||||
},
|
||||
"dirs": {
|
||||
"c00_吕萍_idle_left": {
|
||||
@ -379,6 +381,33 @@
|
||||
"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_捡球男孩_关键帧": {
|
||||
"path": "res://asset/art/animation/c01_捡球男孩_关键帧",
|
||||
"frames": {
|
||||
@ -1357,7 +1386,8 @@
|
||||
"c02_黑手_捂屏幕": "c02_黑手_捂屏幕",
|
||||
"c02_吕萍_爬行_idle_l": "laying_stay_l",
|
||||
"c02_吕萍_爬行_idle_r": "laying_stay_r",
|
||||
"c02_吕萍_爬行_left": "laying_moving_l"
|
||||
"c02_吕萍_爬行_left": "laying_moving_l",
|
||||
"c01_信碎片_falling": "c01_信碎片_falling"
|
||||
},
|
||||
"frames_per_second": {
|
||||
"c00_吕萍_idle_left": 2,
|
||||
@ -1409,6 +1439,7 @@
|
||||
"c02_黑手_捂屏幕": 9,
|
||||
"c02_吕萍_爬行_idle_l": 2,
|
||||
"c02_吕萍_爬行_idle_r": 2,
|
||||
"c02_吕萍_爬行_left": 6
|
||||
"c02_吕萍_爬行_left": 6,
|
||||
"c01_信碎片_falling": 7
|
||||
}
|
||||
}
|
@ -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
|
@ -11,9 +11,10 @@ class_name GameEvent extends Resource
|
||||
# * 事件订阅机制:订阅开始/进度/成功/失败,触发特定响应
|
||||
# * 消费器能力:执行 CG(锁定/无锁定,剧本/特效) / 执行实体变化脚本(赠送/消耗/状态变化)
|
||||
# * 保存与加载
|
||||
@export var event_id: int
|
||||
@export var packed_time: PackedTime
|
||||
@export var scene: String
|
||||
@export var scene_position: Vector2
|
||||
@export var ground: String
|
||||
@export var ground_position: Vector2
|
||||
@export var entity: String
|
||||
@export var entity_action: String
|
||||
@export var need_to_save := false
|
||||
@export var extra_data = {}
|
||||
|
@ -2,16 +2,15 @@ class_name GameEventMatcher extends Resource
|
||||
|
||||
# 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
|
||||
@export var entity: String
|
||||
# empty means any action
|
||||
@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
|
||||
func match(event: GameEvent) -> bool:
|
||||
@ -19,23 +18,21 @@ func match(event: GameEvent) -> bool:
|
||||
return false
|
||||
if entity_actions.size() > 0 and !entity_actions.has(event.entity_action):
|
||||
return false
|
||||
if scenes.size() > 0 and !scenes.has(event.scene):
|
||||
return false
|
||||
if chapter_section.size() > 0:
|
||||
if grounds.size() > 0:
|
||||
var chapter := str(event.packed_time.chapter)
|
||||
var section := str(event.packed_time.section)
|
||||
var matched := false
|
||||
for chapter_section_matcher in chapter_section:
|
||||
for ground_matcher in grounds:
|
||||
# regex match
|
||||
var parts = chapter_section_matcher.split("_")
|
||||
var parts = ground_matcher.split("_")
|
||||
if parts.size() != 2:
|
||||
continue
|
||||
var chapter_matcher = parts[0]
|
||||
var section_matcher = parts[1]
|
||||
if chapter_matcher == "*" or chapter_matcher == chapter:
|
||||
matched = true
|
||||
break
|
||||
if section_matcher == "*" or section_matcher == section:
|
||||
var chapter_matcher = parts[0].strip_edges()
|
||||
var section_matcher = parts[1].strip_edges()
|
||||
if (
|
||||
(chapter_matcher == "*" or chapter_matcher == chapter)
|
||||
and (section_matcher == "*" or section_matcher == section)
|
||||
):
|
||||
matched = true
|
||||
break
|
||||
if !matched:
|
||||
|
@ -16,9 +16,13 @@ func get_player() -> MainPlayer:
|
||||
return get_node_or_null("/root/Main/MainPlayer") as MainPlayer
|
||||
|
||||
|
||||
func get_current_selected_prop() -> String:
|
||||
var prop_hud = get_node_or_null("/root/Main/UILayer/PropHUD") as PropHud
|
||||
if prop_hud and prop_hud.selected:
|
||||
func get_prop_hud() -> PropHud:
|
||||
return get_node_or_null("/root/Main/UILayer/PropHUD") as PropHud
|
||||
|
||||
|
||||
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 ""
|
||||
|
||||
|
@ -4,13 +4,16 @@ extends Node
|
||||
# { entity: [MatcherConsumer] }
|
||||
var _event_registry: Dictionary = {}
|
||||
|
||||
class MatcherConsumer extends RefCounted:
|
||||
var _matcher: GameEventMatcher
|
||||
var _consumer: Callable
|
||||
|
||||
func _init(matcher: GameEventMatcher, consumer: Callable) -> void:
|
||||
self._matcher = matcher
|
||||
self._consumer = consumer
|
||||
class MatcherConsumer:
|
||||
extends RefCounted
|
||||
@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:
|
||||
@ -21,6 +24,7 @@ func register_event_matcher(event_matcher: GameEventMatcher, consumer: Callable)
|
||||
_event_registry[event_matcher.entity] = []
|
||||
_event_registry[event_matcher.entity].append(matcher_consumer)
|
||||
|
||||
|
||||
# 触发事件
|
||||
func trigger_event(event: GameEvent) -> void:
|
||||
if event.entity not in _event_registry:
|
||||
@ -29,3 +33,15 @@ func trigger_event(event: GameEvent) -> void:
|
||||
# matcher_consumer = matcher_consumer as MatcherConsumer
|
||||
if matcher_consumer._matcher.match(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
|
||||
|
@ -63,7 +63,6 @@ window/size/window_width_override=1692
|
||||
window/size/window_height_override=948
|
||||
window/subwindows/embed_subwindows=false
|
||||
window/stretch/mode="canvas_items"
|
||||
window/stretch/scale_mode="integer"
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_iwrfx"]
|
||||
resource_local_to_scene = true
|
||||
size = Vector2(40, 70)
|
||||
size = Vector2(10, 70)
|
||||
|
||||
[node name="Ambush" type="Node2D"]
|
||||
script = ExtResource("1_rxgbr")
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_gffp4"]
|
||||
resource_local_to_scene = true
|
||||
size = Vector2(35, 70)
|
||||
size = Vector2(20, 70)
|
||||
|
||||
[node name="HdEntity" type="Marker2D"]
|
||||
script = ExtResource("1_fp2a8")
|
||||
|
@ -3,14 +3,16 @@ extends Sprite2D
|
||||
|
||||
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_after: Texture2D
|
||||
@export var one_shot := true
|
||||
@export var interacted_times := 0
|
||||
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 area2d = %Area2D as Area2D
|
||||
|
||||
@ -42,29 +44,61 @@ func _ready() -> void:
|
||||
area2d.body_exited.connect(_on_cancel)
|
||||
sign_mark.interacted.connect(_on_interacted)
|
||||
sign_mark.cancel.connect(_on_cancel)
|
||||
sign_mark.base_scale = sign_mark.scale
|
||||
|
||||
|
||||
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:
|
||||
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:
|
||||
if one_shot and interacted_times:
|
||||
return
|
||||
sfx.play()
|
||||
var key = SceneManager.get_current_selected_prop()
|
||||
# print("prop_key", key)
|
||||
var key = SceneManager.get_current_prop(false)
|
||||
var prop_hud = SceneManager.get_prop_hud() as PropHud
|
||||
if key != prop_key:
|
||||
sfx_invalid.play()
|
||||
sign_mark.invalid_shake()
|
||||
# prop_hud.on_toggle_invalid_prop()
|
||||
return
|
||||
sfx_success.play()
|
||||
if one_shot:
|
||||
prop_hud.disable_prop_item(prop_key)
|
||||
else:
|
||||
prop_hud.on_toggle_valid_prop()
|
||||
interacted_times += 1
|
||||
if texture_after:
|
||||
texture = texture_after
|
||||
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]:
|
||||
|
@ -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="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="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"]
|
||||
resource_local_to_scene = true
|
||||
@ -10,14 +21,24 @@ size = Vector2(35, 70)
|
||||
|
||||
[node name="Interactable" type="Sprite2D"]
|
||||
script = ExtResource("1_6nrd3")
|
||||
unmatched_sign_texture = SubResource("AtlasTexture_0gwq7")
|
||||
matched_sign_texture = SubResource("AtlasTexture_0ks5m")
|
||||
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"
|
||||
|
||||
[node name="Sign" parent="." instance=ExtResource("3_qsms8")]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="Sprite2D" parent="Sign/TextureContainer" index="0"]
|
||||
texture = SubResource("AtlasTexture_0gwq7")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
@ -25,3 +46,5 @@ collision_layer = 0
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
unique_name_in_owner = true
|
||||
shape = SubResource("RectangleShape2D_8d3b4")
|
||||
|
||||
[editable path="Sign"]
|
||||
|
@ -42,13 +42,14 @@ var inspected_time = 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
$InspectLayer.layer = GlobalConfig.CANVAS_LAYER_PROP_INSPECTOR
|
||||
sign_mark.interacted.connect(_on_interacted)
|
||||
sign_mark.cancel.connect(_on_cancel)
|
||||
|
||||
container.modulate.a = 0.0
|
||||
content_label.text = _get_tr_content()
|
||||
tip_label.text = tip_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():
|
||||
if content_key == "":
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]
|
||||
resource_local_to_scene = true
|
||||
size = Vector2(35, 70)
|
||||
size = Vector2(20, 70)
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_c3c2j"]
|
||||
line_spacing = 1.0
|
||||
@ -27,8 +27,8 @@ file = "纸条.mp3"
|
||||
|
||||
[node name="Sign" parent="." instance=ExtResource("4_do8tr")]
|
||||
unique_name_in_owner = true
|
||||
offset_top = -8.0
|
||||
offset_bottom = 72.0
|
||||
offset_top = -14.0
|
||||
offset_bottom = -14.0
|
||||
|
||||
[node name="PointLight2D" type="PointLight2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
@ -17,9 +17,9 @@ signal read_note
|
||||
if is_node_ready():
|
||||
notify_property_list_changed()
|
||||
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):
|
||||
editor_filter = val
|
||||
title_filter = val
|
||||
if is_node_ready():
|
||||
notify_property_list_changed()
|
||||
|
||||
@ -52,31 +52,39 @@ func _on_interacted() -> void:
|
||||
printerr("Note key is not set")
|
||||
return
|
||||
%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:
|
||||
"os":
|
||||
_show_os()
|
||||
_show_os(_res, title)
|
||||
"ballon":
|
||||
_show_balloon()
|
||||
_show_balloon(_res, title)
|
||||
read_note.emit()
|
||||
|
||||
|
||||
func _show_os():
|
||||
func _show_os(res, title):
|
||||
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:
|
||||
lines.append(current_line)
|
||||
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:
|
||||
break
|
||||
SceneManager.pop_os(lines)
|
||||
SceneManager.freeze_player(1.0, "")
|
||||
|
||||
|
||||
func _show_balloon():
|
||||
func _show_balloon(res, title):
|
||||
# SceneManager.focus_node(self)
|
||||
# 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
|
||||
SceneManager.freeze_player(0, "")
|
||||
interacting = true
|
||||
@ -109,11 +117,23 @@ func _get(property: StringName) -> Variant:
|
||||
func _get_property_list() -> Array[Dictionary]:
|
||||
# only show notes_ properties in editor
|
||||
var titles = ""
|
||||
if Engine.is_editor_hint() and editor_filter and editor_filter != "none":
|
||||
var filted_titles = dialogue_res.get_ordered_titles().filter(_filter_property)
|
||||
var title_arr = []
|
||||
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)
|
||||
else:
|
||||
titles = ",".join(dialogue_res.get_ordered_titles())
|
||||
titles = ",".join(title_arr)
|
||||
return [
|
||||
{
|
||||
"name": "note_key",
|
||||
@ -125,7 +145,7 @@ func _get_property_list() -> Array[Dictionary]:
|
||||
|
||||
|
||||
func _filter_property(property: StringName) -> bool:
|
||||
return property.find(editor_filter) >= 0
|
||||
return property.find(title_filter) >= 0
|
||||
|
||||
|
||||
func _on_cancel(_body = null):
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_k6och"]
|
||||
resource_local_to_scene = true
|
||||
size = Vector2(40, 60)
|
||||
size = Vector2(20, 60)
|
||||
|
||||
[node name="Note" type="Sprite2D"]
|
||||
script = ExtResource("1_3igk8")
|
||||
|
@ -78,7 +78,7 @@ size = Vector2(61, 112.75)
|
||||
[node name="Npc" type="AnimatedSprite2D"]
|
||||
sprite_frames = ExtResource("3_1e8sl")
|
||||
animation = &"c02_张胖子_idle"
|
||||
frame_progress = 0.195431
|
||||
frame_progress = 0.83643
|
||||
script = ExtResource("1_jegr2")
|
||||
dialogue_title = ""
|
||||
|
||||
|
@ -42,7 +42,7 @@ func _on_interacted() -> void:
|
||||
if not texture_note:
|
||||
texture_note = texture_cover
|
||||
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
|
||||
sign_mark.show_sign = false
|
||||
|
||||
|
@ -22,8 +22,10 @@ file = "物品查看.mp3"
|
||||
|
||||
[node name="Sign" parent="." instance=ExtResource("4_1yty8")]
|
||||
unique_name_in_owner = true
|
||||
offset_top = -7.0
|
||||
offset_bottom = 73.0
|
||||
offset_left = -0.5
|
||||
offset_top = -10.5
|
||||
offset_right = -0.5
|
||||
offset_bottom = 69.5
|
||||
|
||||
[node name="PointLight2D" type="PointLight2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
@ -20,10 +20,10 @@ file = "令牌道具获取.wav"
|
||||
|
||||
[node name="Sign" parent="." instance=ExtResource("4_44f4h")]
|
||||
unique_name_in_owner = true
|
||||
offset_left = 1.0
|
||||
offset_top = -35.0
|
||||
offset_right = 1.0
|
||||
offset_bottom = -35.0
|
||||
offset_left = -0.5
|
||||
offset_top = -24.5
|
||||
offset_right = -0.5
|
||||
offset_bottom = -24.5
|
||||
|
||||
[node name="PointLight2D" type="PointLight2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_munml"]
|
||||
resource_local_to_scene = true
|
||||
size = Vector2(45, 130)
|
||||
size = Vector2(25, 130)
|
||||
|
||||
[node name="portal_left" type="Sprite2D"]
|
||||
script = ExtResource("1_jyh6v")
|
||||
@ -20,10 +20,13 @@ file = "页面转换声.wav"
|
||||
|
||||
[node name="Sign" parent="." instance=ExtResource("4_ty1ds")]
|
||||
unique_name_in_owner = true
|
||||
offset_top = -63.0
|
||||
offset_top = -67.5
|
||||
offset_right = 347.0
|
||||
offset_bottom = 271.0
|
||||
offset_bottom = 266.5
|
||||
scale = Vector2(0.05, 0.05)
|
||||
|
||||
[node name="Sprite2D" parent="Sign/TextureContainer" index="0"]
|
||||
position = Vector2(0, 10)
|
||||
texture = ExtResource("2_ay30q")
|
||||
|
||||
[node name="PointLight2D" type="PointLight2D" parent="."]
|
||||
@ -39,3 +42,5 @@ unique_name_in_owner = true
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
shape = SubResource("RectangleShape2D_munml")
|
||||
|
||||
[editable path="Sign"]
|
||||
|
@ -1,14 +1,6 @@
|
||||
@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:
|
||||
set(val):
|
||||
show_sign = val
|
||||
@ -16,17 +8,26 @@ class_name Sign extends TextureRect
|
||||
modulate.a = 1.0
|
||||
else:
|
||||
modulate.a = 0.0
|
||||
@export var draw_shadow := false
|
||||
|
||||
signal interacted
|
||||
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 _pending_activate_sign := [] as Array[NodePath]
|
||||
# 使用互斥锁保证线程安全。在操作 occupied 或 _pending_activate_sign 时需要先锁定,操作完成后解锁
|
||||
static var mutex = Mutex.new()
|
||||
|
||||
var activated = false
|
||||
var activated = false:
|
||||
set(val):
|
||||
activated = val
|
||||
queue_redraw()
|
||||
# var sprite2d = Sprite2D.new()
|
||||
var base_scale = Vector2.ONE
|
||||
|
||||
@ -45,11 +46,6 @@ func _ready() -> void:
|
||||
modulate.a = 0
|
||||
|
||||
|
||||
# func _load_sprite() -> void:
|
||||
# sprite2d.texture = texture
|
||||
# sprite2d.scale = base_scale
|
||||
|
||||
|
||||
func activate(_body: Node2D) -> void:
|
||||
# point_light.energy = 1.0
|
||||
if not is_node_ready():
|
||||
@ -75,8 +71,28 @@ func activate(_body: Node2D) -> void:
|
||||
# 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:
|
||||
# release_focus()
|
||||
# release_focus()d
|
||||
mutex.lock()
|
||||
if activated:
|
||||
activated = false
|
||||
@ -114,3 +130,30 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
var viewport = get_viewport()
|
||||
if viewport:
|
||||
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)
|
||||
|
@ -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="Script" path="res://scene/entity/ux/sign.gd" id="2_kaoka"]
|
||||
|
||||
[node name="Sign" type="TextureRect"]
|
||||
offset_right = 83.0
|
||||
offset_bottom = 80.0
|
||||
[node name="Sign" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
scale = Vector2(0.2, 0.2)
|
||||
pivot_offset = Vector2(-10, -10)
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("1_40b58")
|
||||
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")
|
||||
|
@ -1,25 +1,34 @@
|
||||
@tool
|
||||
class_name Ground2D extends Node2D
|
||||
|
||||
@export var scene_config: SceneConfig
|
||||
# @export var build_boarder := false:
|
||||
# set(new_val):
|
||||
# build_boarder = false
|
||||
# _build_boarder()
|
||||
@export var reload := false:
|
||||
set(new_val):
|
||||
reload = false
|
||||
load_config()
|
||||
@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":
|
||||
set(val):
|
||||
footstep_type = val
|
||||
if is_node_ready():
|
||||
_load_footstep_audio()
|
||||
|
||||
|
||||
@onready var directional_light := %DirectionalLight2D as DirectionalLight2D
|
||||
@onready var foreground = %ParallaxForeground as ParallaxBackground
|
||||
|
||||
var footstep_audio = RandomAudioStreamPlayer.new()
|
||||
|
||||
|
||||
func play_footstep_sound() -> void:
|
||||
if not footstep_audio.audio_collections.is_empty():
|
||||
footstep_audio.play_random()
|
||||
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"),
|
||||
}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -27,37 +36,17 @@ func _ready() -> void:
|
||||
# %ColorRectTop.visible = true
|
||||
# %ColorRectBottom.visible = true
|
||||
add_child(footstep_audio)
|
||||
load_config()
|
||||
_load_footstep_audio()
|
||||
|
||||
|
||||
func load_config():
|
||||
if not scene_config:
|
||||
return
|
||||
var type = scene_config.footstep_type
|
||||
func _load_footstep_audio():
|
||||
# foot step sound
|
||||
footstep_audio.audio_collections.clear()
|
||||
if type != "none":
|
||||
var audio = SceneConfig.FOOTSTEP_AUDIO[type] as AudioStreamCollection
|
||||
if footstep_type != "none":
|
||||
var audio = FOOTSTEP_AUDIO[footstep_type] as AudioStreamCollection
|
||||
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:
|
||||
# if scene_config and scene_config.boarder and $StaticBody2D/CollisionPolygon2D:
|
||||
# $StaticBody2D/CollisionPolygon2D.polygon = scene_config.boarder
|
||||
func play_footstep_sound() -> void:
|
||||
if not footstep_audio.audio_collections.is_empty():
|
||||
footstep_audio.play_random()
|
||||
|
@ -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://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="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"]
|
||||
script/source = "extends CanvasLayer
|
||||
|
||||
@ -22,7 +13,6 @@ func _ready() -> void:
|
||||
|
||||
[node name="Ground" type="Node2D"]
|
||||
script = ExtResource("1_0vrlo")
|
||||
scene_config = SubResource("Resource_6ux50")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
|
||||
|
@ -13,6 +13,7 @@ class_name GroundLoader extends Node2D
|
||||
@export var archive_scene := ""
|
||||
@export var archive_portal := ""
|
||||
|
||||
var first_entered := true
|
||||
var ground: Ground2D
|
||||
|
||||
var scenes_dir = "res://scene/ground/scene/"
|
||||
@ -68,6 +69,7 @@ func transition_to_scene(key: String, portal: String, immediately := false) -> v
|
||||
if immediately:
|
||||
_do_transition(scene)
|
||||
# 更新玩家位置
|
||||
if first_entered:
|
||||
_update_player_position()
|
||||
else:
|
||||
var tween = create_tween() as Tween
|
||||
@ -79,6 +81,7 @@ func transition_to_scene(key: String, portal: String, immediately := false) -> v
|
||||
tween.tween_interval(0.2)
|
||||
tween.tween_callback(_do_transition.bind(scene))
|
||||
tween.tween_callback(func(): player.action_locked = false)
|
||||
first_entered = false
|
||||
else:
|
||||
print("Scene not found: " + key)
|
||||
|
||||
@ -92,20 +95,20 @@ func _update_player_position():
|
||||
# print("update player position", ArchiveManager.archive.player_global_position)
|
||||
player.global_position = ArchiveManager.archive.player_global_position
|
||||
# fixed y
|
||||
if ground.scene_config and ground.scene_config.player_y_fixed:
|
||||
player.global_position.y = ground.scene_config.player_y
|
||||
if ground.player_y_fixed:
|
||||
player.global_position.y = ground.player_y
|
||||
player.set_facing_direction(ArchiveManager.archive.player_direction)
|
||||
|
||||
|
||||
func _do_transition(scene: Node2D):
|
||||
if ground:
|
||||
ground.queue_free()
|
||||
# 提前移除,防止命名冲突
|
||||
remove_child(ground)
|
||||
ground.queue_free()
|
||||
ground = scene.get_child(0)
|
||||
scene.remove_child(ground)
|
||||
scene.queue_free()
|
||||
ground.owner = null
|
||||
scene.queue_free()
|
||||
add_child(ground)
|
||||
ground.name = "Ground"
|
||||
_set_camera_and_player_boundary()
|
||||
@ -114,8 +117,12 @@ func _do_transition(scene: Node2D):
|
||||
if portal_node and not Engine.is_editor_hint():
|
||||
var player = SceneManager.get_player()
|
||||
if player:
|
||||
# player.global_position.x = -20.0
|
||||
player.global_position.x = portal_node.global_position.x
|
||||
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():
|
||||
_watch_scene_update()
|
||||
|
||||
|
@ -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="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://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"]
|
||||
@ -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://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="Texture2D" uid="uid://cyqnkcx3qx100" path="res://asset/art/scene/c01/s05_院长房间/l_房间背景.png" id="15_6p040"]
|
||||
|
||||
[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 = ""
|
||||
[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="RectangleShape2D" id="RectangleShape2D_6i5gw"]
|
||||
resource_local_to_scene = true
|
||||
@ -45,7 +37,6 @@ size = Vector2(35, 70)
|
||||
[node name="S05院长房间" type="Node2D"]
|
||||
|
||||
[node name="Ground" parent="." instance=ExtResource("1_ff4yb")]
|
||||
scene_config = SubResource("Resource_6jwab")
|
||||
|
||||
[node name="BGSprite2D" parent="Ground" index="2"]
|
||||
position = Vector2(23, -118)
|
||||
@ -78,7 +69,7 @@ texture = ExtResource("8_mnduo")
|
||||
[node name="桌椅" parent="Ground/DeployLayer" index="5" instance=ExtResource("10_18v0g")]
|
||||
position = Vector2(154, 42)
|
||||
texture = ExtResource("9_x837o")
|
||||
editor_filter = "c01"
|
||||
title_filter = "c01"
|
||||
note_key = "c01_院长书桌"
|
||||
|
||||
[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")]
|
||||
position = Vector2(277, -28)
|
||||
texture = ExtResource("11_6gq1s")
|
||||
editor_filter = "c01"
|
||||
title_filter = "notes"
|
||||
note_key = "notes_挂画"
|
||||
|
||||
[node name="Sign" parent="Ground/DeployLayer/画框" index="1"]
|
||||
offset_left = 6.0
|
||||
offset_top = -1.0
|
||||
offset_right = 89.0
|
||||
offset_bottom = 79.0
|
||||
offset_left = 3.0
|
||||
offset_top = -7.0
|
||||
offset_right = 86.0
|
||||
offset_bottom = 73.0
|
||||
|
||||
[node name="CollisionShape2D" parent="Ground/DeployLayer/画框/Area2D" index="0"]
|
||||
position = Vector2(11, -1)
|
||||
@ -106,7 +98,7 @@ shape = SubResource("RectangleShape2D_6bim4")
|
||||
[node name="鸡毛掸子" parent="Ground/DeployLayer" index="7" instance=ExtResource("10_18v0g")]
|
||||
position = Vector2(269, 20)
|
||||
texture = ExtResource("12_jtglg")
|
||||
editor_filter = "c01"
|
||||
title_filter = "c01"
|
||||
note_key = "c01_鸡毛掸子"
|
||||
|
||||
[node name="Area2D" parent="Ground/DeployLayer/鸡毛掸子" index="3"]
|
||||
@ -116,24 +108,37 @@ position = Vector2(-7, 0)
|
||||
shape = SubResource("RectangleShape2D_dq2na")
|
||||
|
||||
[node name="Interactable" parent="Ground/DeployLayer" index="8" instance=ExtResource("14_lq1ou")]
|
||||
position = Vector2(210, 36)
|
||||
position = Vector2(207, 30)
|
||||
one_shot = false
|
||||
prop_key = "prop_令牌"
|
||||
prop_key = "prop_1012钥匙"
|
||||
|
||||
[node name="CollisionShape2D" parent="Ground/DeployLayer/Interactable/Area2D" index="0"]
|
||||
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
|
||||
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
|
||||
height = 40.0
|
||||
height = 50.0
|
||||
|
||||
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
|
||||
position = Vector2(22, 49)
|
||||
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"]
|
||||
visible = false
|
||||
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/Interactable"]
|
||||
[editable path="Ground/DeployLayer/Interactable/Sign"]
|
||||
|
@ -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="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="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"]
|
||||
|
||||
[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="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")
|
||||
|
||||
[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"]
|
||||
position = Vector2(392, 2)
|
||||
portal_name = "right"
|
||||
target_scene = "c02_s02"
|
||||
target_portal = "left"
|
||||
|
||||
|
@ -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="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="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"]
|
||||
@ -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="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
|
||||
script = ExtResource("2_757mj")
|
||||
player_y_fixed = true
|
||||
player_y = 45
|
||||
footstep_type = "concrete"
|
||||
bgm = ""
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_0xrg2"]
|
||||
size = Vector2(40, 150)
|
||||
size = Vector2(35, 70)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_3qhvr"]
|
||||
resource_local_to_scene = true
|
||||
@ -30,22 +22,17 @@ size = Vector2(35, 70)
|
||||
[node name="S02" type="Node2D"]
|
||||
|
||||
[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")
|
||||
|
||||
[node name="PortalLeft" parent="Ground/DeployLayer" index="0"]
|
||||
position = Vector2(24, 1)
|
||||
|
||||
[node name="PortalRight" parent="Ground/DeployLayer" index="1"]
|
||||
position = Vector2(676, 3)
|
||||
[node name="portal_right" parent="Ground/DeployLayer" index="1"]
|
||||
position = Vector2(678, 6)
|
||||
target_scene = "c02_s03"
|
||||
target_portal = "left"
|
||||
|
||||
[node name="几张卫生宣传画" parent="Ground/DeployLayer" index="2" instance=ExtResource("3_fy0o1")]
|
||||
position = Vector2(275, -30)
|
||||
editor_filter = "c02"
|
||||
note_key = "c02_卫生宣传画"
|
||||
|
||||
[node name="鼠疫海报" parent="Ground/DeployLayer" index="3" instance=ExtResource("12_0fckv")]
|
||||
@ -54,19 +41,21 @@ texture_cover = ExtResource("7_wdwbi")
|
||||
content_key = "c02_鼠疫海报"
|
||||
|
||||
[node name="纸人" parent="Ground/DeployLayer" index="4" instance=ExtResource("5_nhtbp")]
|
||||
position = Vector2(601, 44)
|
||||
position = Vector2(599, 44)
|
||||
texture = ExtResource("7_xsghn")
|
||||
flip_h = true
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Ground/DeployLayer/纸人"]
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
[node name="Sign" parent="Ground/DeployLayer/纸人" index="1"]
|
||||
offset_left = -63.5
|
||||
offset_top = -114.0
|
||||
offset_right = -63.5
|
||||
offset_bottom = -34.0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/纸人/StaticBody2D"]
|
||||
shape = SubResource("RectangleShape2D_0xrg2")
|
||||
[node name="CollisionShape2D" parent="Ground/DeployLayer/纸人/Area2D" index="0"]
|
||||
shape = SubResource("RectangleShape2D_vc6i4")
|
||||
|
||||
[node name="Ambush" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_70vqn")]
|
||||
position = Vector2(502, 56)
|
||||
position = Vector2(502, 54)
|
||||
hook_animation = null
|
||||
lock_player_on_playing_dialogue = null
|
||||
hook_dialogue_res = null
|
||||
@ -78,10 +67,10 @@ texture = ExtResource("11_x0h3x")
|
||||
sprite_ref = NodePath("../../SubViewportContainer/SubViewport/HdLayer/car")
|
||||
|
||||
[node name="Sign" parent="Ground/DeployLayer/HdEntity" index="1"]
|
||||
offset_left = 1.0
|
||||
offset_top = -28.0
|
||||
offset_right = 84.0
|
||||
offset_bottom = 52.0
|
||||
offset_left = -9.0
|
||||
offset_top = -32.0
|
||||
offset_right = 74.0
|
||||
offset_bottom = 48.0
|
||||
|
||||
[node name="CollisionShape2D" parent="Ground/DeployLayer/HdEntity/Area2D" index="0"]
|
||||
shape = SubResource("RectangleShape2D_3qhvr")
|
||||
@ -90,4 +79,5 @@ shape = SubResource("RectangleShape2D_3qhvr")
|
||||
texture = null
|
||||
|
||||
[editable path="Ground"]
|
||||
[editable path="Ground/DeployLayer/纸人"]
|
||||
[editable path="Ground/DeployLayer/HdEntity"]
|
||||
|
@ -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://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="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"]
|
||||
@ -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://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"]
|
||||
diffuse_texture = ExtResource("3_78bcp")
|
||||
normal_texture = ExtResource("4_nef6w")
|
||||
@ -31,26 +22,27 @@ size = Vector2(40, 70)
|
||||
[node name="S03" type="Node2D"]
|
||||
|
||||
[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")
|
||||
|
||||
[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_portal = "right"
|
||||
|
||||
[node name="PortalRight" parent="Ground/DeployLayer" index="1"]
|
||||
visible = false
|
||||
[node name="portal_right" parent="Ground/DeployLayer" index="1"]
|
||||
position = Vector2(629, 2)
|
||||
|
||||
[node name="Npc" parent="Ground/DeployLayer" index="2" instance=ExtResource("2_r5smg")]
|
||||
position = Vector2(465, 23)
|
||||
frame_progress = 0.94813
|
||||
frame_progress = 0.663565
|
||||
character_name = "张胖子"
|
||||
dialogue_title = "张胖子_01"
|
||||
|
||||
[node name="Note" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_6x7xl")]
|
||||
position = Vector2(268, -36)
|
||||
note_key = "c02_老鼠洞2"
|
||||
|
||||
[node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_gg4jv")]
|
||||
position = Vector2(343, 33)
|
||||
@ -63,7 +55,8 @@ shape = SubResource("RectangleShape2D_ec3g1")
|
||||
|
||||
[node name="Interactable" parent="Ground/DeployLayer" index="5" instance=ExtResource("8_vdelk")]
|
||||
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")]
|
||||
position = Vector2(845, -25)
|
||||
@ -85,7 +78,7 @@ texture = ExtResource("7_icddm")
|
||||
position = Vector2(-12, -143)
|
||||
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)
|
||||
|
||||
[editable path="Ground"]
|
||||
|
@ -1,6 +1,8 @@
|
||||
@tool
|
||||
class_name PropHud extends Control
|
||||
|
||||
signal current_item_changed(prop_key: String)
|
||||
|
||||
@export_group("DebugItem")
|
||||
@export var enable_item := false:
|
||||
set(value):
|
||||
@ -9,17 +11,26 @@ class_name PropHud extends Control
|
||||
enable_prop_item(item_key)
|
||||
@export var item_key: String
|
||||
@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 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:
|
||||
set(value):
|
||||
selected = value
|
||||
if is_node_ready():
|
||||
%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 right_btn = %RightButton as TextureButton
|
||||
@onready var panel = %HudPanel as TextureButton
|
||||
@ -31,7 +42,7 @@ class_name PropHud extends Control
|
||||
var items_dict := {}
|
||||
# 从配置文件加载 prop items
|
||||
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 listen_mouse = false
|
||||
@ -78,15 +89,21 @@ func _load_items():
|
||||
var current_line = item_config_res.lines[id]
|
||||
while current_line:
|
||||
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 inspect_path = ""
|
||||
for t in current_line.tags:
|
||||
if t.begins_with(wrapped):
|
||||
texture_path = t.replace(wrapped, "").strip_edges()
|
||||
break
|
||||
if t.begins_with(wrapped_texture):
|
||||
texture_path = t.replace(wrapped_texture, "").strip_edges()
|
||||
elif t.begins_with(wrapped_inspect):
|
||||
inspect_path = t.replace(wrapped_inspect, "").strip_edges()
|
||||
var item = PropItem.new()
|
||||
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
|
||||
if not current_line.has("next_id") or current_line.next_id == "end":
|
||||
break
|
||||
@ -109,7 +126,10 @@ func _load_texture_cache() -> void:
|
||||
if not key in items_dict:
|
||||
inventory.enabled_items.erase(key)
|
||||
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:
|
||||
cached_inventory_textures[key] = texture
|
||||
# wrap index
|
||||
@ -135,7 +155,9 @@ func _update_prop_display_with_texture():
|
||||
|
||||
|
||||
func on_left_pressed() -> void:
|
||||
sfx.play()
|
||||
if locked:
|
||||
return
|
||||
sfx_click.play()
|
||||
_mouse_moved_on_listening()
|
||||
if inventory.index_wrap_add(-1):
|
||||
selected = false
|
||||
@ -144,7 +166,9 @@ func on_left_pressed() -> void:
|
||||
|
||||
|
||||
func on_right_pressed() -> void:
|
||||
sfx.play()
|
||||
if locked:
|
||||
return
|
||||
sfx_click.play()
|
||||
_mouse_moved_on_listening()
|
||||
if inventory.index_wrap_add(1):
|
||||
selected = false
|
||||
@ -165,7 +189,9 @@ func _tween_container(left_to_right := true) -> void:
|
||||
|
||||
|
||||
func _on_panel_pressed() -> void:
|
||||
sfx.play()
|
||||
if locked:
|
||||
return
|
||||
sfx_click.play()
|
||||
if not selected:
|
||||
focus_mode = FOCUS_ALL
|
||||
grab_focus()
|
||||
@ -174,6 +200,8 @@ func _on_panel_pressed() -> void:
|
||||
|
||||
|
||||
func _on_mouse_entered() -> void:
|
||||
if locked:
|
||||
return
|
||||
listen_mouse = true
|
||||
_mouse_moved_on_listening()
|
||||
|
||||
@ -256,6 +284,16 @@ func enable_prop_item(prop_key: String) -> void:
|
||||
_update_prop_display_with_texture()
|
||||
# save to archive immediately
|
||||
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:
|
||||
@ -266,3 +304,44 @@ func disable_prop_item(prop_key: String) -> void:
|
||||
_update_prop_display_with_texture()
|
||||
# save to archive immediately
|
||||
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()
|
||||
|
@ -31,7 +31,7 @@ mouse_filter = 0
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
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
|
||||
|
||||
[node name="LeftMargin" type="MarginContainer" parent="VBoxContainer/HBoxContainer"]
|
||||
|
@ -1,7 +1,14 @@
|
||||
class_name PropInventory extends Resource
|
||||
|
||||
signal current_item_changed(prop_key: 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():
|
||||
@ -13,7 +20,8 @@ func current_item_key():
|
||||
func enable_item(prop_key: String) -> void:
|
||||
if not enabled_items.has(prop_key):
|
||||
enabled_items.append(prop_key)
|
||||
# emit_changed()
|
||||
# 新增后直接选中
|
||||
current_index = enabled_items.find(prop_key)
|
||||
|
||||
|
||||
func disable_item(prop_key: String) -> void:
|
||||
@ -25,7 +33,6 @@ func disable_item(prop_key: String) -> void:
|
||||
|
||||
# return true if the index changed
|
||||
func index_wrap_add(delta: int) -> bool:
|
||||
# auto wrapped in setter
|
||||
current_index += delta
|
||||
current_index = wrapi(current_index, 0, enabled_items.size())
|
||||
# emit_changed()
|
||||
return not enabled_items.is_empty()
|
||||
|
@ -3,3 +3,4 @@ class_name PropItem extends Resource
|
||||
# unique name
|
||||
@export var key := ""
|
||||
@export_file("*.png") var texture_path := ""
|
||||
@export_file("*.png") var inspect_path := ""
|
||||
|
@ -74,6 +74,7 @@ metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="PropHUD" parent="UILayer" instance=ExtResource("4_t7gb2")]
|
||||
scale = Vector2(0.24, 0.24)
|
||||
item_key = "prop_令牌"
|
||||
display_time = 1.5
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
@tool
|
||||
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
|
||||
signal quit
|
||||
@ -16,7 +16,7 @@ var texture_cover: Texture2D
|
||||
var texture_notes: Texture2D
|
||||
|
||||
var status := STATUS_HIDDEN
|
||||
var blinking_tween : Tween
|
||||
var blinking_tween: Tween
|
||||
|
||||
|
||||
# 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))
|
||||
|
||||
|
||||
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
|
||||
visible = true
|
||||
texture_rect.texture = cover_texture
|
||||
@ -72,18 +74,38 @@ func pop_inspection(cover_texture, notes_texture, inspection_note):
|
||||
SceneManager.freeze_player(0)
|
||||
var tween = create_tween()
|
||||
tween.tween_property(texture_rect, "modulate:a", 1.0, 0.15)
|
||||
tip_label.text = tip_cover
|
||||
_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:
|
||||
if status == STATUS_HIDDEN:
|
||||
return
|
||||
if event.is_action_pressed("cancel"):
|
||||
quit.emit()
|
||||
_hide()
|
||||
get_viewport().set_input_as_handled()
|
||||
_hide()
|
||||
quit.emit()
|
||||
if event.is_action_pressed("interact"):
|
||||
get_viewport().set_input_as_handled()
|
||||
# STATUS_INSPECTING_COVER 与 STATUS_INSPECTING_NOTES 之间互相切换
|
||||
if status == STATUS_INSPECTING_COVER:
|
||||
# inspect notes
|
||||
status = STATUS_INSPECTING_NOTES
|
||||
@ -96,3 +118,7 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
texture_rect.texture = texture_cover
|
||||
tip_label.text = tip_cover
|
||||
create_tween().tween_property(content_label, "modulate:a", 0.0, 0.2)
|
||||
# STATUS_INSPECTING_PROP 直接退出
|
||||
elif status == STATUS_INSPECTING_PROP:
|
||||
_hide()
|
||||
quit.emit()
|