mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-31 23:29:27 +08:00
feat: 点光源重构
This commit is contained in:
parent
8dba57e222
commit
6417d9218b
@ -10,3 +10,5 @@ script/**/*.js
|
|||||||
public/editor.html
|
public/editor.html
|
||||||
keyCodes.ts
|
keyCodes.ts
|
||||||
src/core/main/setting.ts
|
src/core/main/setting.ts
|
||||||
|
src/core/fx/shadow.ts
|
||||||
|
src/core/fx/shadow_upload.js
|
@ -21,11 +21,12 @@
|
|||||||
"ant-design-vue": "^3.2.20",
|
"ant-design-vue": "^3.2.20",
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
"chart.js": "^4.4.0",
|
"chart.js": "^4.4.0",
|
||||||
|
"gl-matrix": "^3.4.3",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lz-string": "^1.5.0",
|
"lz-string": "^1.5.0",
|
||||||
"mutate-animate": "^1.3.3",
|
"mutate-animate": "^1.3.3",
|
||||||
"three": "^0.149.0",
|
"pixi.js": "^8.1.0",
|
||||||
"vue": "^3.3.4"
|
"vue": "^3.3.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -23,6 +23,9 @@ dependencies:
|
|||||||
chart.js:
|
chart.js:
|
||||||
specifier: ^4.4.0
|
specifier: ^4.4.0
|
||||||
version: 4.4.0
|
version: 4.4.0
|
||||||
|
gl-matrix:
|
||||||
|
specifier: ^3.4.3
|
||||||
|
version: 3.4.3
|
||||||
jszip:
|
jszip:
|
||||||
specifier: ^3.10.1
|
specifier: ^3.10.1
|
||||||
version: 3.10.1
|
version: 3.10.1
|
||||||
@ -35,9 +38,9 @@ dependencies:
|
|||||||
mutate-animate:
|
mutate-animate:
|
||||||
specifier: ^1.3.3
|
specifier: ^1.3.3
|
||||||
version: 1.3.3
|
version: 1.3.3
|
||||||
three:
|
pixi.js:
|
||||||
specifier: ^0.149.0
|
specifier: ^8.1.0
|
||||||
version: 0.149.0
|
version: 8.1.0
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.3.4
|
specifier: ^3.3.4
|
||||||
version: 3.3.4
|
version: 3.3.4
|
||||||
@ -2181,6 +2184,10 @@ packages:
|
|||||||
semver: 7.5.4
|
semver: 7.5.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@pixi/colord@2.9.6:
|
||||||
|
resolution: {integrity: sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@pkgjs/parseargs@0.11.0:
|
/@pkgjs/parseargs@0.11.0:
|
||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@ -2364,6 +2371,14 @@ packages:
|
|||||||
'@babel/types': 7.22.15
|
'@babel/types': 7.22.15
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/css-font-loading-module@0.0.12:
|
||||||
|
resolution: {integrity: sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/earcut@2.1.4:
|
||||||
|
resolution: {integrity: sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/estree@1.0.1:
|
/@types/estree@1.0.1:
|
||||||
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
|
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -2634,10 +2649,13 @@ packages:
|
|||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@webgpu/types@0.1.40:
|
||||||
|
resolution: {integrity: sha512-/BBkHLS6/eQjyWhY2H7Dx5DHcVrS2ICj9owvSRdgtQT6KcafLZA86tPze0xAOsd4FbsYKCUBUQyNi87q7gV7kw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@xmldom/xmldom@0.8.10:
|
/@xmldom/xmldom@0.8.10:
|
||||||
resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==}
|
resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/abbrev@1.1.1:
|
/abbrev@1.1.1:
|
||||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||||
@ -3357,6 +3375,10 @@ packages:
|
|||||||
stream-shift: 1.0.1
|
stream-shift: 1.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/earcut@2.2.4:
|
||||||
|
resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/eastasianwidth@0.2.0:
|
/eastasianwidth@0.2.0:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -3466,6 +3488,10 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eventemitter3@5.0.1:
|
||||||
|
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/exponential-backoff@3.1.1:
|
/exponential-backoff@3.1.1:
|
||||||
resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==}
|
resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -3696,6 +3722,10 @@ packages:
|
|||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/gl-matrix@3.4.3:
|
||||||
|
resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/glob-parent@3.1.0:
|
/glob-parent@3.1.0:
|
||||||
resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==}
|
resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -4069,6 +4099,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/ismobilejs@1.1.1:
|
||||||
|
resolution: {integrity: sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/jackspeak@2.3.3:
|
/jackspeak@2.3.3:
|
||||||
resolution: {integrity: sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==}
|
resolution: {integrity: sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@ -4651,6 +4685,10 @@ packages:
|
|||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/parse-svg-path@0.1.2:
|
||||||
|
resolution: {integrity: sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/path-dirname@1.0.2:
|
/path-dirname@1.0.2:
|
||||||
resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==}
|
resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -4703,6 +4741,20 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pixi.js@8.1.0:
|
||||||
|
resolution: {integrity: sha512-qclFipWxKavNZoOE0QjGgEklbxjc1mpHf46adsxYLz7O7RnV44PPkq1J5Ssa6y1JxtYUX0fwbphoE/gz276glA==}
|
||||||
|
dependencies:
|
||||||
|
'@pixi/colord': 2.9.6
|
||||||
|
'@types/css-font-loading-module': 0.0.12
|
||||||
|
'@types/earcut': 2.1.4
|
||||||
|
'@webgpu/types': 0.1.40
|
||||||
|
'@xmldom/xmldom': 0.8.10
|
||||||
|
earcut: 2.2.4
|
||||||
|
eventemitter3: 5.0.1
|
||||||
|
ismobilejs: 1.1.1
|
||||||
|
parse-svg-path: 0.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-attribute-case-insensitive@6.0.3(postcss@8.4.29):
|
/postcss-attribute-case-insensitive@6.0.3(postcss@8.4.29):
|
||||||
resolution: {integrity: sha512-KHkmCILThWBRtg+Jn1owTnHPnFit4OkqS+eKiGEOPIGke54DCeYGJ6r0Fx/HjfE9M9kznApCLcU0DvnPchazMQ==}
|
resolution: {integrity: sha512-KHkmCILThWBRtg+Jn1owTnHPnFit4OkqS+eKiGEOPIGke54DCeYGJ6r0Fx/HjfE9M9kznApCLcU0DvnPchazMQ==}
|
||||||
engines: {node: ^14 || ^16 || >=18}
|
engines: {node: ^14 || ^16 || >=18}
|
||||||
@ -5596,10 +5648,6 @@ packages:
|
|||||||
source-map-support: 0.5.21
|
source-map-support: 0.5.21
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/three@0.149.0:
|
|
||||||
resolution: {integrity: sha512-tohpUxPDht0qExRLDTM8sjRLc5d9STURNrdnK3w9A+V4pxaTBfKWWT/IqtiLfg23Vfc3Z+ImNfvRw1/0CtxrkQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/through2-filter@3.0.0:
|
/through2-filter@3.0.0:
|
||||||
resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==}
|
resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -28,11 +28,10 @@ main.floors.MT50=
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"5,13": [
|
"5,13": [
|
||||||
"欢迎来到苍蓝之殿,这是本塔第二章里面最大的一个区,也是最复杂的一个区。整个苍蓝之殿分为无个部分:左下角、右下角、左上角、右上角和中心,每个部分都有不一样的玩法,多多动脑哦。",
|
"欢迎来到苍蓝之殿,这是本塔第二章里面最大的一个区,也是最复杂的一个区。整个苍蓝之殿分为无个部分:左下角、右下角、左上角、右上角和中心,每个部分都有不一样的玩法,多多动脑哦。"
|
||||||
"本地图往上走会有一个商店,记得查看"
|
|
||||||
],
|
],
|
||||||
"9,13": [
|
"9,13": [
|
||||||
"在你刚进入苍蓝之殿时,你只能先前往左下角部分(本地图的左面),右下角暂时不能前往。"
|
"在你刚进入苍蓝之殿时,你只能先前往左下角部分(本地图的左面),右下角暂时不能前往。注意往上走往左依然可以进入左下角,不要只盯着这个地图的左边不放。"
|
||||||
],
|
],
|
||||||
"9,1": [
|
"9,1": [
|
||||||
"建议优先点出学习技能,对于特定场景将会非常有帮助",
|
"建议优先点出学习技能,对于特定场景将会非常有帮助",
|
||||||
|
@ -31,6 +31,13 @@ main.floors.MT51=
|
|||||||
14,
|
14,
|
||||||
8
|
8
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"7,0": {
|
||||||
|
"floorId": "MT53",
|
||||||
|
"loc": [
|
||||||
|
7,
|
||||||
|
14
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"beforeBattle": {},
|
"beforeBattle": {},
|
||||||
|
@ -1,45 +1,65 @@
|
|||||||
main.floors.MT53=
|
main.floors.MT53=
|
||||||
{
|
{
|
||||||
"floorId": "MT53",
|
"floorId": "MT53",
|
||||||
"title": "苍蓝之殿-左下",
|
"title": "苍蓝之殿-左下",
|
||||||
"name": "53",
|
"name": "53",
|
||||||
"width": 15,
|
"width": 15,
|
||||||
"height": 15,
|
"height": 15,
|
||||||
"canFlyTo": true,
|
"canFlyTo": true,
|
||||||
"canFlyFrom": true,
|
"canFlyFrom": true,
|
||||||
"canUseQuickShop": true,
|
"canUseQuickShop": true,
|
||||||
"cannotViewMap": false,
|
"cannotViewMap": false,
|
||||||
"images": [],
|
"images": [],
|
||||||
"ratio": 8,
|
"ratio": 8,
|
||||||
"defaultGround": "T650",
|
"defaultGround": "T650",
|
||||||
"bgm": "palaceSouth.mp3",
|
"bgm": "palaceSouth.mp3",
|
||||||
"firstArrive": [],
|
"firstArrive": [],
|
||||||
"eachArrive": [],
|
"eachArrive": [],
|
||||||
"parallelDo": "",
|
"parallelDo": "",
|
||||||
"events": {},
|
"events": {},
|
||||||
"changeFloor": {},
|
"changeFloor": {
|
||||||
"beforeBattle": {},
|
"7,14": {
|
||||||
"afterBattle": {},
|
"floorId": "MT51",
|
||||||
"afterGetItem": {},
|
"loc": [
|
||||||
"afterOpenDoor": {},
|
7,
|
||||||
"autoEvent": {},
|
0
|
||||||
"cannotMove": {},
|
]
|
||||||
"cannotMoveIn": {},
|
}
|
||||||
"map": [
|
},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"beforeBattle": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"afterBattle": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"afterGetItem": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"afterOpenDoor": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"autoEvent": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"cannotMove": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"cannotMoveIn": {},
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"map": [
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[648,648,648,648,648,648,648,648,648,648,648,648,648,648,648],
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[648,656, 0,219,648, 0, 0, 0,243, 0, 0,492,482,482,648],
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[648, 0,648, 0,648,648,648,578,648,648,656,648,648,648,648],
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[648, 0,648, 0,648, 0, 0, 0,648, 0, 0,648, 0, 0,648],
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[648, 0,648,563,492, 0, 0, 0,648, 0, 0,240, 0, 0,648],
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[648, 0,648,648,648,648,494,648,648,219,648,648,648,648,648],
|
||||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
[648, 0,578, 0,648,403, 0,484,648, 0, 0,648, 0, 0,648],
|
||||||
|
[ 92, 0,648, 0,648, 0, 21, 0,648, 0, 0,220, 0, 0, 94],
|
||||||
|
[648,648,648, 0,648,376, 0,378,648, 0, 0,648, 0, 0,648],
|
||||||
|
[648, 0,648, 0,648,648,249,648,648,219,648,648,648,648,648],
|
||||||
|
[648, 0,648, 0, 0,596, 0, 0,648, 0, 0,539, 0, 0,648],
|
||||||
|
[648, 0,243, 0, 0,648, 0, 0,648, 0, 0,648, 0, 0,648],
|
||||||
|
[648,601,648,648,648,648,243,648,648,648,539,648, 0, 0,648],
|
||||||
|
[648, 0, 0, 0, 0,648, 0, 0, 0, 0, 0,656, 0, 0,648],
|
||||||
|
[648,648,648,648,648,648,648, 93,648,648,648,648,648,648,648]
|
||||||
],
|
],
|
||||||
|
"bgmap": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"fgmap": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"bg2map": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"fg2map": [
|
||||||
|
|
||||||
|
]
|
||||||
}
|
}
|
@ -82,6 +82,8 @@ export class BgmController
|
|||||||
if (!this.disable) {
|
if (!this.disable) {
|
||||||
this.setTransitionAnimate(id, 1, when);
|
this.setTransitionAnimate(id, 1, when);
|
||||||
if (this.now) this.setTransitionAnimate(this.now, 0);
|
if (this.now) this.setTransitionAnimate(this.now, 0);
|
||||||
|
} else {
|
||||||
|
this.playing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!noStack) {
|
if (!noStack) {
|
||||||
@ -134,6 +136,8 @@ export class BgmController
|
|||||||
if (!this.disable) {
|
if (!this.disable) {
|
||||||
if (transition) this.setTransitionAnimate(this.now, 1);
|
if (transition) this.setTransitionAnimate(this.now, 1);
|
||||||
else this.get(this.now).play();
|
else this.get(this.now).play();
|
||||||
|
} else {
|
||||||
|
this.playing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +175,8 @@ export class BgmController
|
|||||||
this.redoStack = [];
|
this.redoStack = [];
|
||||||
}
|
}
|
||||||
this.now = id;
|
this.now = id;
|
||||||
|
} else {
|
||||||
|
this.playing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1268
src/core/fx/shadow.ts
Normal file
1268
src/core/fx/shadow.ts
Normal file
File diff suppressed because it is too large
Load Diff
1480
src/core/fx/shadow_upload.js
Normal file
1480
src/core/fx/shadow_upload.js
Normal file
File diff suppressed because it is too large
Load Diff
298
src/core/fx/webgl.ts
Normal file
298
src/core/fx/webgl.ts
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
import { ensureArray, tip } from '@/plugin/utils';
|
||||||
|
import { sleep } from 'mutate-animate';
|
||||||
|
import { logger } from '../common/logger';
|
||||||
|
|
||||||
|
const { gl, gl2 } = checkSupport();
|
||||||
|
|
||||||
|
function checkSupport() {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const canvas2 = document.createElement('canvas');
|
||||||
|
const gl = canvas.getContext('webgl');
|
||||||
|
const gl2 = canvas2.getContext('webgl2');
|
||||||
|
if (!gl) {
|
||||||
|
sleep(3000).then(() => {
|
||||||
|
tip(
|
||||||
|
'warning',
|
||||||
|
`您的浏览器不支持WebGL,大部分特效将会无法显示,建议使用新版浏览器`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!gl2) {
|
||||||
|
sleep(3000).then(() => {
|
||||||
|
tip(
|
||||||
|
'warning',
|
||||||
|
`您的浏览器不支持WebGL2,一部分特效将会无法显示,建议使用新版浏览器`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { gl: !!gl, gl2: !!gl2 };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isWebGLSupported() {
|
||||||
|
return gl;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isWebGL2Supported() {
|
||||||
|
return gl2;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WebGLColorArray = [number, number, number, number];
|
||||||
|
|
||||||
|
interface WebGLShaderInfo {
|
||||||
|
vertex: WebGLShader;
|
||||||
|
fragment: WebGLShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
type UniformBinderNum = 1 | 2 | 3 | 4;
|
||||||
|
type UniformBinderType = 'f' | 'i';
|
||||||
|
type UniformFunc<
|
||||||
|
N extends UniformBinderNum,
|
||||||
|
T extends UniformBinderType,
|
||||||
|
V extends 'v' | ''
|
||||||
|
> = `uniform${N}${T}${V}`;
|
||||||
|
|
||||||
|
type UniformBinderValue<N extends UniformBinderNum> = N extends 1
|
||||||
|
? number
|
||||||
|
: N extends 2
|
||||||
|
? [number, number]
|
||||||
|
: N extends 3
|
||||||
|
? [number, number, number]
|
||||||
|
: [number, number, number, number];
|
||||||
|
|
||||||
|
interface UniformBinder<
|
||||||
|
N extends UniformBinderNum,
|
||||||
|
T extends UniformBinderType,
|
||||||
|
V extends 'v' | ''
|
||||||
|
> {
|
||||||
|
value: UniformBinderValue<N>;
|
||||||
|
set(value: UniformBinderValue<N>): void;
|
||||||
|
get(): UniformBinderValue<N>;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class WebGLBase {
|
||||||
|
abstract canvas: HTMLCanvasElement;
|
||||||
|
abstract gl: WebGLRenderingContext | WebGL2RenderingContext;
|
||||||
|
|
||||||
|
background: WebGLColorArray = [0, 0, 0, 0];
|
||||||
|
|
||||||
|
vsSource: string = '';
|
||||||
|
fsSource: string = '';
|
||||||
|
|
||||||
|
program: WebGLProgram | null = null;
|
||||||
|
shader: WebGLShaderInfo | null = null;
|
||||||
|
|
||||||
|
resetCanvas() {
|
||||||
|
this.gl.clearColor(...this.background);
|
||||||
|
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSize(width: number, height: number) {
|
||||||
|
this.canvas.width = width;
|
||||||
|
this.canvas.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
compile() {
|
||||||
|
const gl = this.gl;
|
||||||
|
gl.deleteProgram(this.program);
|
||||||
|
gl.deleteShader(this.shader?.vertex ?? null);
|
||||||
|
gl.deleteShader(this.shader?.fragment ?? null);
|
||||||
|
|
||||||
|
this.program = this.createProgram();
|
||||||
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
||||||
|
gl.useProgram(this.program);
|
||||||
|
}
|
||||||
|
|
||||||
|
vs(vs: string) {
|
||||||
|
this.vsSource = vs;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs(fs: string) {
|
||||||
|
this.fsSource = fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个全局变量绑定器,用于操作全局变量
|
||||||
|
* @param uniform 全局变量的变量名
|
||||||
|
* @param num 变量的元素数量,float和int视为1,vec2 vec3 vec4分别视为 2 3 4
|
||||||
|
* @param type 数据类型,可以填'f',表示浮点型,或者填'i',表示整型
|
||||||
|
* @param vector 是否为向量,可以填'v',表示是向量,或者填'',表示不是向量
|
||||||
|
* @returns 一个uniform绑定器,用于操作全局变量uniform
|
||||||
|
*/
|
||||||
|
createUniformBinder<
|
||||||
|
N extends UniformBinderNum,
|
||||||
|
T extends UniformBinderType,
|
||||||
|
V extends 'v' | ''
|
||||||
|
>(uniform: string, num: N, type: T, vector: V): UniformBinder<N, T, V> {
|
||||||
|
if (!this.program) {
|
||||||
|
throw new Error(
|
||||||
|
`Uniform binder should be use when the program initialized.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const suffix = `${num}${type}${vector ? 'v' : ''}`;
|
||||||
|
const func = `uniform${suffix}` as UniformFunc<N, T, V>;
|
||||||
|
const value = (
|
||||||
|
num === 1 ? 0 : Array(num).fill(0)
|
||||||
|
) as UniformBinderValue<N>;
|
||||||
|
|
||||||
|
const loc = this.gl.getUniformLocation(this.program, uniform);
|
||||||
|
const gl = this.gl;
|
||||||
|
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
set(value) {
|
||||||
|
this.value = value;
|
||||||
|
let v;
|
||||||
|
if (vector === 'v') {
|
||||||
|
let _v = ensureArray(value);
|
||||||
|
if (type === 'f') {
|
||||||
|
v = new Float32Array(_v);
|
||||||
|
} else {
|
||||||
|
v = new Int32Array(_v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = ensureArray(value);
|
||||||
|
}
|
||||||
|
// 对uniform赋值
|
||||||
|
if (vector === 'v') {
|
||||||
|
// @ts-ignore
|
||||||
|
gl[func](loc, v);
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
gl[func](loc, ...v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected createProgram() {
|
||||||
|
const gl = this.gl;
|
||||||
|
const vs = this.loadShader(gl.VERTEX_SHADER, this.vsSource);
|
||||||
|
const fs = this.loadShader(gl.FRAGMENT_SHADER, this.fsSource);
|
||||||
|
|
||||||
|
this.shader = {
|
||||||
|
vertex: vs,
|
||||||
|
fragment: fs
|
||||||
|
};
|
||||||
|
|
||||||
|
const program = gl.createProgram()!;
|
||||||
|
gl.attachShader(program, vs);
|
||||||
|
gl.attachShader(program, fs);
|
||||||
|
gl.linkProgram(program);
|
||||||
|
|
||||||
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
||||||
|
logger.error(
|
||||||
|
9,
|
||||||
|
`Cannot initialize shader program. Error info: ${gl.getProgramInfoLog(
|
||||||
|
program
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected loadShader(type: number, source: string) {
|
||||||
|
const gl = this.gl;
|
||||||
|
const shader = gl.createShader(type)!;
|
||||||
|
gl.shaderSource(shader, source);
|
||||||
|
gl.compileShader(shader);
|
||||||
|
|
||||||
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||||
|
throw new Error(
|
||||||
|
`Cannot compile ${
|
||||||
|
type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'
|
||||||
|
} shader. Error info: ${gl.getShaderInfoLog(shader)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WebGLCanvas extends WebGLBase {
|
||||||
|
canvas: HTMLCanvasElement;
|
||||||
|
gl: WebGLRenderingContext;
|
||||||
|
|
||||||
|
constructor(canvas?: HTMLCanvasElement) {
|
||||||
|
super();
|
||||||
|
this.canvas = canvas ?? document.createElement('canvas');
|
||||||
|
this.gl = this.canvas.getContext('webgl')!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WebGL2Canvas extends WebGLBase {
|
||||||
|
canvas: HTMLCanvasElement;
|
||||||
|
gl: WebGL2RenderingContext;
|
||||||
|
|
||||||
|
constructor(canvas?: HTMLCanvasElement) {
|
||||||
|
super();
|
||||||
|
this.canvas = canvas ?? document.createElement('canvas');
|
||||||
|
this.gl = this.canvas.getContext('webgl2')!;
|
||||||
|
}
|
||||||
|
|
||||||
|
vs(vs: string): void {
|
||||||
|
if (!vs.startsWith('#version 300 es')) {
|
||||||
|
this.vsSource = `#version 300 es\n` + vs;
|
||||||
|
} else {
|
||||||
|
this.vsSource = vs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs(fs: string): void {
|
||||||
|
if (!fs.startsWith('#version 300 es')) {
|
||||||
|
this.fsSource = `#version 300 es\n` + fs;
|
||||||
|
} else {
|
||||||
|
this.vsSource = fs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadShader(
|
||||||
|
gl: WebGLRenderingContext,
|
||||||
|
type: number,
|
||||||
|
source: string
|
||||||
|
) {
|
||||||
|
const shader = gl.createShader(type)!;
|
||||||
|
gl.shaderSource(shader, source);
|
||||||
|
gl.compileShader(shader);
|
||||||
|
|
||||||
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||||
|
logger.error(
|
||||||
|
10,
|
||||||
|
`Cannot compile ${
|
||||||
|
type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'
|
||||||
|
} shader. Error info: ${gl.getShaderInfoLog(shader)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createProgram(
|
||||||
|
gl: WebGLRenderingContext,
|
||||||
|
vsSource: string,
|
||||||
|
fsSource: string
|
||||||
|
) {
|
||||||
|
const vs = loadShader(gl, gl.VERTEX_SHADER, vsSource);
|
||||||
|
const fs = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
|
||||||
|
|
||||||
|
const program = gl.createProgram()!;
|
||||||
|
gl.attachShader(program, vs);
|
||||||
|
gl.attachShader(program, fs);
|
||||||
|
gl.linkProgram(program);
|
||||||
|
|
||||||
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
||||||
|
logger.error(
|
||||||
|
9,
|
||||||
|
`Cannot initialize shader program. Error info: ${gl.getProgramInfoLog(
|
||||||
|
program
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
@ -59,6 +59,7 @@ import { MCGenerator } from './main/layout';
|
|||||||
import { ResourceController } from './loader/controller';
|
import { ResourceController } from './loader/controller';
|
||||||
import { logger } from './common/logger';
|
import { logger } from './common/logger';
|
||||||
import { Danmaku } from './main/custom/danmaku';
|
import { Danmaku } from './main/custom/danmaku';
|
||||||
|
import * as Shadow from './fx/shadow';
|
||||||
|
|
||||||
// ----- 类注册
|
// ----- 类注册
|
||||||
Mota.register('class', 'AudioPlayer', AudioPlayer);
|
Mota.register('class', 'AudioPlayer', AudioPlayer);
|
||||||
@ -131,6 +132,7 @@ Mota.register('module', 'UIComponents', {
|
|||||||
Keyboard: KeyboardPanel
|
Keyboard: KeyboardPanel
|
||||||
});
|
});
|
||||||
Mota.register('module', 'MCGenerator', MCGenerator);
|
Mota.register('module', 'MCGenerator', MCGenerator);
|
||||||
|
Mota.register('module', 'Shadow', Shadow);
|
||||||
|
|
||||||
main.renderLoaded = true;
|
main.renderLoaded = true;
|
||||||
Mota.require('var', 'hook').emit('renderLoaded');
|
Mota.require('var', 'hook').emit('renderLoaded');
|
||||||
|
@ -160,7 +160,7 @@ export class Danmaku extends EventEmitter<DanmakuEvent> {
|
|||||||
this.posted = false;
|
this.posted = false;
|
||||||
this.posting = false;
|
this.posting = false;
|
||||||
logger.error(
|
logger.error(
|
||||||
3,
|
1,
|
||||||
`Unexpected error when posting danmaku. Error info: ${e}`
|
`Unexpected error when posting danmaku. Error info: ${e}`
|
||||||
);
|
);
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
|
@ -53,6 +53,7 @@ export {};
|
|||||||
}
|
}
|
||||||
core.updateStatusBar(true, true);
|
core.updateStatusBar(true, true);
|
||||||
}
|
}
|
||||||
|
Mota.require('module', 'Shadow').Shadow.update(true);
|
||||||
console.log(`Floor hot reload: ${data}`);
|
console.log(`Floor hot reload: ${data}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,35 +15,35 @@ import { setCanvasFilterByFloorId } from '../fx/gameCanvas';
|
|||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
// 勇士身上的光源
|
// 勇士身上的光源
|
||||||
Mota.rewrite(core.control, 'drawHero', 'add', () => {
|
// Mota.rewrite(core.control, 'drawHero', 'add', () => {
|
||||||
if (core.getFlag('__heroOpacity__') !== 0) {
|
// if (core.getFlag('__heroOpacity__') !== 0) {
|
||||||
getAllLights().forEach(v => {
|
// getAllLights().forEach(v => {
|
||||||
if (!v.followHero) return;
|
// if (!v.followHero) return;
|
||||||
v._offset ??= { x: v.x, y: v.y };
|
// v._offset ??= { x: v.x, y: v.y };
|
||||||
v.x = core.status.heroCenter.px + v._offset.x;
|
// v.x = core.status.heroCenter.px + v._offset.x;
|
||||||
v.y = core.status.heroCenter.py + v._offset.y;
|
// v.y = core.status.heroCenter.py + v._offset.y;
|
||||||
refreshLight();
|
// refreshLight();
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
// 更新地形数据
|
// // 更新地形数据
|
||||||
Mota.rewrite(core.maps, 'removeBlock', 'add', success => {
|
// Mota.rewrite(core.maps, 'removeBlock', 'add', success => {
|
||||||
if (success && main.replayChecking) updateShadow(true);
|
// if (success && main.replayChecking) updateShadow(true);
|
||||||
return success;
|
// return success;
|
||||||
});
|
// });
|
||||||
Mota.rewrite(core.maps, 'setBlock', 'add', () => {
|
// Mota.rewrite(core.maps, 'setBlock', 'add', () => {
|
||||||
if (main.replayChecking) updateShadow(true);
|
// if (main.replayChecking) updateShadow(true);
|
||||||
});
|
// });
|
||||||
Mota.rewrite(core.events, 'changingFloor', 'add', (_, floorId) => {
|
// Mota.rewrite(core.events, 'changingFloor', 'add', (_, floorId) => {
|
||||||
if (!main.replayChecking) {
|
// if (!main.replayChecking) {
|
||||||
updateShadow();
|
// updateShadow();
|
||||||
setCanvasFilterByFloorId(floorId);
|
// setCanvasFilterByFloorId(floorId);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
// 初始化画布信息
|
// // 初始化画布信息
|
||||||
Mota.rewrite(core.ui, 'deleteAllCanvas', 'add', () => {
|
// Mota.rewrite(core.ui, 'deleteAllCanvas', 'add', () => {
|
||||||
if (main.mode === 'play' && !main.replayChecking) initShadowCanvas();
|
// if (main.mode === 'play' && !main.replayChecking) initShadowCanvas();
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
const shadowInfo: Partial<Record<FloorIds, Light[]>> = {
|
const shadowInfo: Partial<Record<FloorIds, Light[]>> = {
|
||||||
|
@ -131,6 +131,7 @@ function showCursor() {
|
|||||||
* 设置光标位置
|
* 设置光标位置
|
||||||
*/
|
*/
|
||||||
function setCursor(ele: HTMLSpanElement, i: number) {
|
function setCursor(ele: HTMLSpanElement, i: number) {
|
||||||
|
if (!ele) return;
|
||||||
const style = getComputedStyle(ele);
|
const style = getComputedStyle(ele);
|
||||||
cursor.style.top = `${
|
cursor.style.top = `${
|
||||||
parseFloat(style.height) * (i + 0.5) -
|
parseFloat(style.height) * (i + 0.5) -
|
||||||
@ -297,6 +298,7 @@ async function setButtonAnimate() {
|
|||||||
|
|
||||||
buttons.forEach(
|
buttons.forEach(
|
||||||
v =>
|
v =>
|
||||||
|
v &&
|
||||||
(v.style.transition =
|
(v.style.transition =
|
||||||
'transform 0.3s ease-out, color 0.3s ease-out')
|
'transform 0.3s ease-out, color 0.3s ease-out')
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user