替换资源和解锁预览效果

master
humingxing 1 week ago
parent a9e39a427b
commit ca02a61a60
  1. 11
      assets/bundles/battleGame/prefab/格子锁.prefab
  2. 14
      assets/bundles/battleGameMonster/prefab/monster/兵.prefab
  3. 2
      assets/bundles/first/config/Battlebuff.json
  4. 640
      assets/bundles/first/config/Rank.json
  5. BIN
      assets/bundles/icons/img/土.png
  6. 134
      assets/bundles/icons/img/土.png.meta
  7. BIN
      assets/bundles/icons/img/木.png
  8. 134
      assets/bundles/icons/img/木.png.meta
  9. BIN
      assets/bundles/icons/img/水.png
  10. 134
      assets/bundles/icons/img/水.png.meta
  11. BIN
      assets/bundles/icons/img/火.png
  12. 134
      assets/bundles/icons/img/火.png.meta
  13. BIN
      assets/bundles/icons/img/金.png
  14. 134
      assets/bundles/icons/img/金.png.meta
  15. 1216
      assets/bundles/popBattle/battleGameResult/prefab/BattlePause.prefab
  16. 9
      assets/res/battleGameMonster/spine/小怪X5.meta
  17. 1
      assets/res/battleGameMonster/spine/小怪X5/.WeDrive
  18. 111
      assets/res/battleGameMonster/spine/小怪X5/小怪X5.atlas
  19. 12
      assets/res/battleGameMonster/spine/小怪X5/小怪X5.atlas.meta
  20. 1
      assets/res/battleGameMonster/spine/小怪X5/小怪X5.json
  21. 13
      assets/res/battleGameMonster/spine/小怪X5/小怪X5.json.meta
  22. BIN
      assets/res/battleGameMonster/spine/小怪X5/小怪X5.png
  23. 134
      assets/res/battleGameMonster/spine/小怪X5/小怪X5.png.meta
  24. BIN
      assets/res/comm/texture/bg/暂停游戏.png
  25. 40
      assets/res/comm/texture/bg/暂停游戏.png.meta
  26. BIN
      assets/res/comm/texture/bg/暂停游戏框体.png
  27. 112
      assets/script/battle/map/legacy/MapAreaUnlock.ts
  28. 369
      assets/script/battle/view/AreaUnlockGuidePresenter.ts
  29. 9
      assets/script/battle/view/AreaUnlockGuidePresenter.ts.meta
  30. 28
      assets/script/battle/view/CocosBagBoardView.ts
  31. 2
      assets/script/game/ConfigRes.ts
  32. 2
      assets/script/game/ResPkgBuilder.ts

@ -92,7 +92,7 @@
},
"_lpos": {
"__type__": "cc.Vec3",
"x": -16.1845703125,
"x": -21.1845703125,
"y": 0,
"z": 0
},
@ -228,7 +228,7 @@
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 13.5,
"x": 18.5,
"y": 0,
"z": 0
},
@ -378,7 +378,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 84.369140625,
"width": 94.369140625,
"height": 68
},
"_anchorPoint": {
@ -461,7 +461,7 @@
"_paddingRight": 10,
"_paddingTop": 0,
"_paddingBottom": 0,
"_spacingX": -10,
"_spacingX": 0,
"_spacingY": 0,
"_verticalDirection": 1,
"_horizontalDirection": 0,
@ -484,6 +484,7 @@
"__id__": 0
},
"fileId": "a01BJWthhKbr3LbCXP7YXR",
"instance": null
"instance": null,
"targetOverrides": null
}
]

@ -127,13 +127,13 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 57,
"height": 49.70000076293945
"width": 60.09000015258789,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5182456300969709,
"y": 0.5760563122992055
"x": 0.4781161502626326,
"y": 0.26
},
"_id": ""
},
@ -164,11 +164,11 @@
"a": 255
},
"_skeletonData": {
"__uuid__": "2ff1a233-3438-41e6-8f86-bff953ab9a68",
"__uuid__": "234ccbbe-0991-444b-9db0-b1211911ea5c",
"__expectedType__": "sp.SkeletonData"
},
"defaultSkin": "兵",
"defaultAnimation": "待机",
"defaultSkin": "default",
"defaultAnimation": "金小怪",
"_premultipliedAlpha": false,
"_timeScale": 1,
"_preCacheMode": 2,

@ -2,7 +2,7 @@
{
"id": 1,
"name": "灾厄盒",
"desc": "对方Boss出现几率翻倍",
"desc": "Boss出现几率翻倍",
"icon": "灾厄盒",
"quality": 2,
"type": 2,

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "483926f6-b44f-4487-b12c-18869e5c2f04",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "483926f6-b44f-4487-b12c-18869e5c2f04@6c48a",
"displayName": "土",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "483926f6-b44f-4487-b12c-18869e5c2f04",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "483926f6-b44f-4487-b12c-18869e5c2f04@f9941",
"displayName": "土",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 22,
"height": 22,
"rawWidth": 22,
"rawHeight": 22,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-11,
-11,
0,
11,
-11,
0,
-11,
11,
0,
11,
11,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
22,
22,
22,
0,
0,
22,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-11,
-11,
0
],
"maxPos": [
11,
11,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "483926f6-b44f-4487-b12c-18869e5c2f04@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "483926f6-b44f-4487-b12c-18869e5c2f04@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "0acc9c84-80da-4619-a205-f5a5f2e2933b",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "0acc9c84-80da-4619-a205-f5a5f2e2933b@6c48a",
"displayName": "木",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "0acc9c84-80da-4619-a205-f5a5f2e2933b",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "0acc9c84-80da-4619-a205-f5a5f2e2933b@f9941",
"displayName": "木",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 22,
"height": 23,
"rawWidth": 22,
"rawHeight": 23,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-11,
-11.5,
0,
11,
-11.5,
0,
-11,
11.5,
0,
11,
11.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
23,
22,
23,
0,
0,
22,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-11,
-11.5,
0
],
"maxPos": [
11,
11.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "0acc9c84-80da-4619-a205-f5a5f2e2933b@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "0acc9c84-80da-4619-a205-f5a5f2e2933b@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "193a9ca0-c402-4984-a744-9484172b90f4",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "193a9ca0-c402-4984-a744-9484172b90f4@6c48a",
"displayName": "水",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "193a9ca0-c402-4984-a744-9484172b90f4",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "193a9ca0-c402-4984-a744-9484172b90f4@f9941",
"displayName": "水",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 22,
"height": 23,
"rawWidth": 22,
"rawHeight": 23,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-11,
-11.5,
0,
11,
-11.5,
0,
-11,
11.5,
0,
11,
11.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
23,
22,
23,
0,
0,
22,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-11,
-11.5,
0
],
"maxPos": [
11,
11.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "193a9ca0-c402-4984-a744-9484172b90f4@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "193a9ca0-c402-4984-a744-9484172b90f4@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "8a795201-91bb-4612-b56b-fc0826b5266e",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "8a795201-91bb-4612-b56b-fc0826b5266e@6c48a",
"displayName": "火",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "8a795201-91bb-4612-b56b-fc0826b5266e",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "8a795201-91bb-4612-b56b-fc0826b5266e@f9941",
"displayName": "火",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 22,
"height": 23,
"rawWidth": 22,
"rawHeight": 23,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-11,
-11.5,
0,
11,
-11.5,
0,
-11,
11.5,
0,
11,
11.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
23,
22,
23,
0,
0,
22,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-11,
-11.5,
0
],
"maxPos": [
11,
11.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "8a795201-91bb-4612-b56b-fc0826b5266e@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "8a795201-91bb-4612-b56b-fc0826b5266e@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "813415dc-5bcd-4d94-b1c7-7298c5b6b62f",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "813415dc-5bcd-4d94-b1c7-7298c5b6b62f@6c48a",
"displayName": "金",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "813415dc-5bcd-4d94-b1c7-7298c5b6b62f",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "813415dc-5bcd-4d94-b1c7-7298c5b6b62f@f9941",
"displayName": "金",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 23,
"height": 23,
"rawWidth": 23,
"rawHeight": 23,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-11.5,
-11.5,
0,
11.5,
-11.5,
0,
-11.5,
11.5,
0,
11.5,
11.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
23,
23,
23,
0,
0,
23,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-11.5,
-11.5,
0
],
"maxPos": [
11.5,
11.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "813415dc-5bcd-4d94-b1c7-7298c5b6b62f@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "813415dc-5bcd-4d94-b1c7-7298c5b6b62f@6c48a"
}
}

@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "ce94753f-1e01-4a6d-9e5e-952d336d3a46",
"files": [],
"subMetas": {},
"userData": {}
}

@ -0,0 +1 @@
D:\WXWork\1688855084654441\WeDrive\中昱智云\抖音游戏\战斗类\【新】2048数字守卫战\动效\数字皮肤+武器\怪物\小怪X5

@ -0,0 +1,111 @@
小怪X5.png
size: 348,142
format: RGBA8888
filter: Linear,Linear
repeat: none
土
rotate: false
xy: 254, 31
size: 23, 25
orig: 25, 27
offset: 1, 1
index: -1
土小怪
rotate: true
xy: 286, 28
size: 46, 48
orig: 48, 50
offset: 1, 1
index: -1
手臂
rotate: true
xy: 336, 64
size: 10, 12
orig: 12, 14
offset: 1, 1
index: -1
木
rotate: false
xy: 245, 6
size: 33, 21
orig: 35, 28
offset: 1, 1
index: -1
木小怪
rotate: false
xy: 53, 4
size: 49, 50
orig: 51, 52
offset: 1, 1
index: -1
水
rotate: true
xy: 217, 0
size: 27, 26
orig: 29, 28
offset: 1, 1
index: -1
水小怪
rotate: true
xy: 104, 18
size: 37, 61
orig: 39, 63
offset: 1, 1
index: -1
火
rotate: false
xy: 280, 7
size: 20, 19
orig: 22, 21
offset: 1, 1
index: -1
火小怪
rotate: false
xy: 0, 5
size: 51, 49
orig: 53, 51
offset: 1, 1
index: -1
烟雾1
rotate: true
xy: 286, 76
size: 66, 59
orig: 68, 61
offset: 1, 1
index: -1
烟雾2
rotate: false
xy: 192, 58
size: 92, 84
orig: 94, 86
offset: 1, 1
index: -1
烟雾3
rotate: false
xy: 0, 56
size: 95, 86
orig: 97, 88
offset: 1, 1
index: -1
烟雾4
rotate: false
xy: 97, 57
size: 93, 85
orig: 95, 87
offset: 1, 1
index: -1
金
rotate: false
xy: 217, 29
size: 35, 27
orig: 43, 29
offset: 7, 1
index: -1
金小怪
rotate: false
xy: 167, 7
size: 48, 48
orig: 50, 50
offset: 1, 1
index: -1

@ -0,0 +1,12 @@
{
"ver": "1.0.0",
"importer": "*",
"imported": true,
"uuid": "177b448e-f3a9-4552-b61c-73fe0fd597b3",
"files": [
".atlas",
".json"
],
"subMetas": {},
"userData": {}
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,13 @@
{
"ver": "1.2.7",
"importer": "spine-data",
"imported": true,
"uuid": "234ccbbe-0991-444b-9db0-b1211911ea5c",
"files": [
".json"
],
"subMetas": {},
"userData": {
"atlasUuid": "177b448e-f3a9-4552-b61c-73fe0fd597b3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "7368e9f2-8522-4425-b272-a68dfa117576",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "7368e9f2-8522-4425-b272-a68dfa117576@6c48a",
"displayName": "小怪X5",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "7368e9f2-8522-4425-b272-a68dfa117576",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "7368e9f2-8522-4425-b272-a68dfa117576@f9941",
"displayName": "小怪X5",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 348,
"height": 142,
"rawWidth": 348,
"rawHeight": 142,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-174,
-71,
0,
174,
-71,
0,
-174,
71,
0,
174,
71,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
142,
348,
142,
0,
0,
348,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-174,
-71,
0
],
"maxPos": [
174,
71,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "7368e9f2-8522-4425-b272-a68dfa117576@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "7368e9f2-8522-4425-b272-a68dfa117576@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@ -2,7 +2,7 @@
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "8d9a7a0c-d32c-4ea2-81d3-281e421c0c47",
"uuid": "a7271246-d5d1-4718-8421-3baaae466ac7",
"files": [
".json",
".png"
@ -10,14 +10,14 @@
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "8d9a7a0c-d32c-4ea2-81d3-281e421c0c47@6c48a",
"displayName": "暂停游戏框体",
"uuid": "a7271246-d5d1-4718-8421-3baaae466ac7@6c48a",
"displayName": "暂停游戏",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "8d9a7a0c-d32c-4ea2-81d3-281e421c0c47",
"imageUuidOrDatabaseUri": "a7271246-d5d1-4718-8421-3baaae466ac7",
"isUuid": true,
"visible": false,
"minfilter": "linear",
@ -34,8 +34,8 @@
},
"f9941": {
"importer": "sprite-frame",
"uuid": "8d9a7a0c-d32c-4ea2-81d3-281e421c0c47@f9941",
"displayName": "暂停游戏框体",
"uuid": "a7271246-d5d1-4718-8421-3baaae466ac7@f9941",
"displayName": "暂停游戏",
"id": "f9941",
"name": "spriteFrame",
"userData": {
@ -46,9 +46,9 @@
"trimX": 0,
"trimY": 0,
"width": 582,
"height": 519,
"height": 522,
"rawWidth": 582,
"rawHeight": 519,
"rawHeight": 522,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -61,16 +61,16 @@
"vertices": {
"rawPosition": [
-291,
-259.5,
-261,
0,
291,
-259.5,
-261,
0,
-291,
259.5,
261,
0,
291,
259.5,
261,
0
],
"indexes": [
@ -83,9 +83,9 @@
],
"uv": [
0,
519,
522,
582,
519,
522,
0,
0,
582,
@ -103,17 +103,17 @@
],
"minPos": [
-291,
-259.5,
-261,
0
],
"maxPos": [
291,
259.5,
261,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "8d9a7a0c-d32c-4ea2-81d3-281e421c0c47@6c48a",
"imageUuidOrDatabaseUri": "a7271246-d5d1-4718-8421-3baaae466ac7@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
@ -129,10 +129,6 @@
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "8d9a7a0c-d32c-4ea2-81d3-281e421c0c47@6c48a",
"compressSettings": {
"useCompressTexture": true,
"presetId": "cfxhmsckdLS61QsbVp4HIL"
}
"redirect": "a7271246-d5d1-4718-8421-3baaae466ac7@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

@ -1,6 +1,7 @@
import { Label, Layout, Node, UITransform, Vec3, isValid } from 'cc';
import { Label, Layout, Node, Sprite, UITransform, Vec3, isValid } from 'cc';
import { SpriteLoad } from 'db://assets/mx/components/SpriteLoad';
import { TableNames } from '../../../game/ConfigTableData';
import { GBundle } from '../../../game/ConfigRes';
import { GBundle, GPath } from '../../../game/ConfigRes';
import { MapGrid } from './MapGrid';
/** 解锁条件气泡预制体路径 */
@ -9,10 +10,16 @@ const LOCK_TIP_PATH = 'prefab/';
const LOCK_TIP_NAME = '格子锁';
/** 预制体上显示数字的子节点名 */
const LOCK_TIP_NUM = 'num';
/** 动态条件图标子节点名前缀 */
const LOCK_TIP_COND = 'cond_';
/** 条件图标占位尺寸(与 icons/img 五行图接近) */
const COND_ICON_SIZE = 22;
/** 气泡世界坐标转本地时复用 */
const _tipWorld = new Vec3();
/** 气泡本地坐标复用 */
const _tipLocal = new Vec3();
/** herotype → 五行图标名(1金 2木 3水 4火 5土) */
const HERO_TYPE_ICON: string[] = ['', '金', '木', '水', '火', '土'];
/**
* 拖英雄推进区域解锁的结果。
@ -63,6 +70,8 @@ export class MapAreaUnlock {
private _warnedSprite = false;
/** 按阵营各挂一个条件气泡 */
private _tips: Node[] = [];
/** 与当前展示中的 _tips 对齐的阵营 CampAreaID */
private _tipCamps: number[] = [];
/**
* 绑定本局关卡与某阵营段位等级加值。
@ -144,6 +153,22 @@ export class MapAreaUnlock {
return this._probe(grid, hero) === 'unlocked';
}
/**
* 某阵营当前格子锁气泡(用于解锁引导连线终点)。
* @param campAreaId 阵营 CampAreaID
*/
tipOf(campAreaId: number): Node | null {
const camp = Math.floor(Number(campAreaId) || 0);
if (camp <= 0) return null;
for (let i = 0; i < this._tipCamps.length; i++) {
if (this._tipCamps[i] !== camp) continue;
const tip = this._tips[i];
if (tip?.isValid && tip.active) return tip;
return null;
}
return null;
}
/**
* 把英雄拖到当前解锁区域。条件与 canDrag 相同,成功则解锁该阵营整区。
* @param grid 落点格
@ -226,7 +251,7 @@ export class MapAreaUnlock {
/** 各阵营当前待解锁区各自挂气泡 */
private _refreshTips(): void {
const jobs: { grids: MapGrid[]; num: number }[] = [];
const jobs: { camp: number; grids: MapGrid[]; num: number; heroType: number }[] = [];
for (let t = 0; t < this._tracks.length; t++) {
const track = this._tracks[t];
const current = this.currentId(track.camp);
@ -235,10 +260,12 @@ export class MapAreaUnlock {
if (index < 0 || !track.rolled[index]) continue;
const group = this._waitingOfCamp(current, track.camp);
if (group.length <= 0) continue;
const num = this._heroNumber(track.needLevels[index], track.heroTypes[index]);
const heroType = track.heroTypes[index] | 0;
const num = this._heroNumber(track.needLevels[index], heroType);
if (!(num > 0)) continue;
jobs.push({ grids: group, num });
jobs.push({ camp: track.camp, grids: group, num, heroType });
}
this._tipCamps.length = 0;
if (jobs.length <= 0) {
this._hideTips();
return;
@ -249,18 +276,24 @@ export class MapAreaUnlock {
}
for (let i = 0; i < jobs.length; i++) {
const tip = this._tips[i];
if (!tip?.isValid) continue;
if (!tip?.isValid) {
this._tipCamps.push(0);
continue;
}
const numNode = tip.getChildByName(LOCK_TIP_NUM);
const label = numNode?.getComponent(Label);
if (!label) {
console.warn('[MapAreaUnlock] 格子锁缺少 num Label');
tip.active = false;
this._tipCamps.push(0);
continue;
}
label.string = String(jobs[i].num);
this._syncCondIcons(tip, jobs[i].heroType);
tip.getComponent(Layout)?.updateLayout();
this._placeTipCenter(tip, jobs[i].grids);
tip.active = true;
this._tipCamps.push(jobs[i].camp);
}
for (let i = jobs.length; i < this._tips.length; i++) {
const tip = this._tips[i];
@ -268,6 +301,70 @@ export class MapAreaUnlock {
}
}
/**
* 同步解锁条件五行图标:类型 0 不加载;1–5 各挂一张对应图标(锁与数字之间)。
* @param tip 格子锁气泡
* @param heroType 当前随机到的 Hero.herotype;0 为无属性限制
*/
private _syncCondIcons(tip: Node, heroType: number): void {
this._clearCondIcons(tip);
const names = this._condIconNames(heroType);
if (names.length <= 0) return;
const numNode = tip.getChildByName(LOCK_TIP_NUM);
let insertAt = numNode ? numNode.getSiblingIndex() : tip.children.length;
for (let i = 0; i < names.length; i++) {
const icon = this._makeCondIcon(names[i]);
tip.insertChild(icon, insertAt);
insertAt++;
}
}
/**
* 当前条件需要展示的五行图标名列表;无限制返回空。
* @param heroType Hero.herotype
*/
private _condIconNames(heroType: number): string[] {
const type = Math.floor(Number(heroType) || 0);
if (type <= 0) return [];
const name = HERO_TYPE_ICON[type];
if (!name) {
console.warn('[MapAreaUnlock] 未知解锁 herotype,无法加载条件图标', type);
return [];
}
return [name];
}
/**
* 创建单张条件图标节点(SpriteLoad 从 icons 包加载)。
* @param name 金/木/水/火/土
*/
private _makeCondIcon(name: string): Node {
const node = new Node(LOCK_TIP_COND + name);
node.layer = 33554432;
const ut = node.addComponent(UITransform);
ut.setContentSize(COND_ICON_SIZE, COND_ICON_SIZE);
const sp = node.addComponent(Sprite);
sp.sizeMode = Sprite.SizeMode.TRIMMED;
node.addComponent(SpriteLoad).setSprite(GPath.ElementAttr(name), GBundle.Items);
return node;
}
/**
* 清除气泡上动态挂的条件图标(池化复用前必须清干净)。
* @param tip 格子锁气泡
*/
private _clearCondIcons(tip: Node): void {
if (!tip?.isValid) return;
const children = tip.children;
for (let i = children.length - 1; i >= 0; i--) {
const child = children[i];
if (!child?.isValid) continue;
if (child.name.indexOf(LOCK_TIP_COND) !== 0) continue;
child.removeFromParent();
child.destroy();
}
}
/**
* 某阵营当前待解锁格。
* @param current 当前区域 ID
@ -372,6 +469,7 @@ export class MapAreaUnlock {
/** 隐藏全部气泡(本局内复用节点) */
private _hideTips(): void {
this._tipCamps.length = 0;
for (let i = 0; i < this._tips.length; i++) {
const tip = this._tips[i];
if (!tip?.isValid) continue;
@ -384,10 +482,12 @@ export class MapAreaUnlock {
for (let i = 0; i < this._tips.length; i++) {
const tip = this._tips[i];
if (!tip || !isValid(tip)) continue;
this._clearCondIcons(tip);
if (tip['resKey']) gg.res.putNode(tip);
else tip.destroy();
}
this._tips.length = 0;
this._tipCamps.length = 0;
}
/**

@ -0,0 +1,369 @@
import { Color, Graphics, Node, Sorting2D, UITransform, Vec3, isValid, sp } from 'cc';
import { isElementGlyphType } from 'db://assets/mx/module/merge';
import { GBundle } from '../../game/ConfigRes';
import { AI_VIEW_LOCAL_CAMP } from '../ai/runtime/AiCampArea';
import type { BattleBagSession } from '../bag/BattleBagSession';
import { WeaponComposeConfigProvider } from '../bag/WeaponComposeConfigProvider';
import type { MapManager } from '../map/legacy/MapManager';
import { BattleSpinePlayback } from '../presentation/BattleSpinePlayback';
import type { TextGrid } from './TextGrid';
/** 引导虚线框预制体路径 */
const FRAME_PATH = 'prefab/障碍物/';
/** 引导虚线框预制体名 */
const FRAME_NAME = '引导虚线框';
/** 虚线框 Spine 动画名 */
const FRAME_ANIM = 'animation';
/** 连线层节点名 */
const LINE_LAYER = 'ui_areaUnlockGuideLine';
/** 黑白交替每段长度(对齐效果图) */
const DASH_LEN = 12;
/** 斑马段半宽(实心矩形,避免细 stroke 在深色底上看不见) */
const DASH_HALF_W = 2.5;
/** 描边相对半宽加宽,保证黑/白段在任意底上都可见 */
const DASH_OUTLINE_EXTRA = 1.5;
/** 背包端取字块顶边中点的向上偏移 */
const BAG_TOP_PAD = 2;
/** 气泡端取底边中点的向下偏移 */
const TIP_BOTTOM_PAD = 2;
/** 虚线框须压在字形之上(textGrid skin Sorting2D order=3,canUpEff=4) */
const FRAME_SORT_LAYER = 3;
/** 虚线框 Sorting2D order */
const FRAME_SORT_ORDER = 6;
/** 交替色:黑 */
const DASH_BLACK = new Color(15, 15, 15, 255);
/** 交替色:白 */
const DASH_WHITE = new Color(255, 255, 255, 255);
/** 世界坐标复用 */
const _bagWorld = new Vec3();
/** 气泡世界坐标复用 */
const _tipWorld = new Vec3();
/** 本地起点复用 */
const _fromLocal = new Vec3();
/** 本地终点复用 */
const _toLocal = new Vec3();
/** 解锁引导刷新入参 */
export interface AreaUnlockGuideRefresh {
/** 本机背包会话 */
bagSession: BattleBagSession;
/** 地图 */
map: MapManager;
/** 阵营 CampAreaID;默认本机下方 */
campAreaId?: number;
/** 取背包槽字块 */
slotGridAt: (slotIndex: number) => TextGrid | null;
/** 槽位是否可拖(开启且非待开启) */
canDragSlot: (slotIndex: number) => boolean;
/** 为 true 时只清不显(拖动中 / 入场中) */
skip?: boolean;
}
/**
* 背包可解锁当前地图区域时:随机标一个背包字 + 连到格子锁气泡。
*/
export class AreaUnlockGuidePresenter {
/** 连线层父节点 */
private _parent: Node | null = null;
/** Graphics 连线层 */
private _lineLayer: Node | null = null;
private _graphics: Graphics | null = null;
/** 背包虚线框 */
private _frame: Node | null = null;
/** 当前标识的背包槽;null 表示未展示 */
private _slotIndex: number | null = null;
/**
* 绑定连线层父节点(须同时覆盖地图与背包,如 BattleGame 根)。
* @param parent 父节点
*/
bind(parent: Node | null): void {
this.unbind();
if (!parent?.isValid) return;
this._parent = parent;
this._ensureLineLayer();
}
/** 释放节点与池资源 */
unbind(): void {
this.clear();
if (this._lineLayer?.isValid) {
this._lineLayer.destroy();
}
this._lineLayer = null;
this._graphics = null;
this._parent = null;
}
/** 当前标识的背包槽;无引导时 null */
get slotIndex(): number | null {
return this._slotIndex;
}
/** 立刻隐藏虚线框与连线 */
clear(): void {
this._slotIndex = null;
this._releaseFrame();
if (this._graphics?.isValid) this._graphics.clear();
if (this._lineLayer?.isValid) this._lineLayer.active = false;
}
/**
* 按背包与当前解锁条件刷新引导。
* 原槽仍可解锁时保持不变,避免频繁乱跳。
*/
refresh(opts: AreaUnlockGuideRefresh): void {
if (opts.skip || !this._parent?.isValid) {
this.clear();
return;
}
const camp = Math.floor(Number(opts.campAreaId) || AI_VIEW_LOCAL_CAMP);
const tip = opts.map.areaUnlock.tipOf(camp);
if (!tip?.isValid) {
this.clear();
return;
}
const current = opts.map.areaUnlock.currentId(camp);
if (current <= 0) {
this.clear();
return;
}
const unlockGrids = opts.map.areaUnlock.gridsOf(current, camp);
if (unlockGrids.length <= 0) {
this.clear();
return;
}
const probeIndex = unlockGrids[0].Index;
const candidates = this._collectCandidates(opts, probeIndex);
if (candidates.length <= 0) {
this.clear();
return;
}
let slot = this._slotIndex;
if (slot == null || !this._listHas(candidates, slot)) {
slot = candidates[Math.floor(Math.random() * candidates.length)];
}
const grid = opts.slotGridAt(slot);
if (!grid?.node?.isValid) {
this.clear();
return;
}
if (!this._attachFrame(grid.node)) {
this.clear();
return;
}
this._slotIndex = slot;
this._drawLine(grid.node, tip);
}
/**
* 收集可解锁当前区域的背包槽。
* @param opts 刷新入参
* @param probeIndex 探测用地图格
*/
private _collectCandidates(opts: AreaUnlockGuideRefresh, probeIndex: number): number[] {
const out: number[] = [];
WeaponComposeConfigProvider.instance.load();
const provider = WeaponComposeConfigProvider.instance;
const slots = opts.bagSession.getBagSlots();
for (let i = 0; i < slots.length; i++) {
const slot = slots[i];
if (!slot) continue;
if (!opts.canDragSlot(i)) continue;
const t = Number(provider.getWeapon2Type(slot.weapon2Id));
if (!isElementGlyphType(t)) continue;
if (!opts.slotGridAt(i)?.node?.isValid) continue;
if (!opts.bagSession.canUnlockArea(probeIndex, slot.weapon2Id, slot.level)) continue;
out.push(i);
}
return out;
}
/**
* @param list 候选槽
* @param slot 槽下标
*/
private _listHas(list: readonly number[], slot: number): boolean {
for (let i = 0; i < list.length; i++) {
if (list[i] === slot) return true;
}
return false;
}
/**
* 把虚线框挂到背包字块上并循环播放。
* @param host 字块节点
*/
private _attachFrame(host: Node): boolean {
if (!this._frame?.isValid) {
if (typeof gg === 'undefined' || !gg.res?.getNode) {
console.warn('[AreaUnlockGuide] gg.res 未就绪,无法加载引导虚线框');
return false;
}
const node = gg.res.getNode(FRAME_PATH, FRAME_NAME, GBundle.BattleMap);
if (!node?.isValid) {
console.warn('[AreaUnlockGuide] 缺少引导虚线框预制体', FRAME_NAME);
return false;
}
this._frame = node;
}
const frame = this._frame;
if (!frame.isValid) return false;
frame.layer = host.layer;
if (frame.parent !== host) {
frame.parent = host;
frame.setPosition(0, 0, 0);
frame.setScale(1, 1, 1);
}
frame.setSiblingIndex(host.children.length - 1);
this._applyFrameSorting(frame);
frame.active = true;
const sk = frame.getComponent(sp.Skeleton) ?? frame.getComponentInChildren(sp.Skeleton);
if (sk?.isValid) {
sk.node.layer = host.layer;
BattleSpinePlayback.play(sk, FRAME_ANIM, { loop: true, optional: true });
}
return true;
}
/**
* 虚线框加 Sorting2D,避免被 textGrid 字形盖住。
* @param frame 引导虚线框
*/
private _applyFrameSorting(frame: Node): void {
let rootSort = frame.getComponent(Sorting2D);
if (!rootSort) rootSort = frame.addComponent(Sorting2D);
rootSort.sortingLayer = FRAME_SORT_LAYER;
rootSort.sortingOrder = FRAME_SORT_ORDER;
const skels = frame.getComponentsInChildren(sp.Skeleton);
for (let i = 0; i < skels.length; i++) {
const n = skels[i]?.node;
if (!n?.isValid) continue;
let sort = n.getComponent(Sorting2D);
if (!sort) sort = n.addComponent(Sorting2D);
sort.sortingLayer = FRAME_SORT_LAYER;
sort.sortingOrder = FRAME_SORT_ORDER;
}
}
/** 归还虚线框 */
private _releaseFrame(): void {
const frame = this._frame;
this._frame = null;
if (!frame || !isValid(frame)) return;
const sk = frame.getComponent(sp.Skeleton) ?? frame.getComponentInChildren(sp.Skeleton);
if (sk?.isValid) {
BattleSpinePlayback.clearPendingComplete(sk);
BattleSpinePlayback.resetTracks(sk);
}
if (frame['resKey']) gg.res.putNode(frame);
else frame.destroy();
}
/** 确保 Graphics 连线层 */
private _ensureLineLayer(): void {
const parent = this._parent;
if (!parent?.isValid) return;
let layer = parent.getChildByName(LINE_LAYER);
if (!layer) {
layer = new Node(LINE_LAYER);
layer.layer = parent.layer;
layer.parent = parent;
layer.setPosition(0, 0, 0);
const ut = layer.addComponent(UITransform);
const parentUt = parent.getComponent(UITransform);
if (parentUt) ut.setContentSize(parentUt.contentSize);
else ut.setContentSize(2000, 2000);
ut.setAnchorPoint(0.5, 0.5);
layer.addComponent(Graphics);
}
this._lineLayer = layer;
this._graphics = layer.getComponent(Graphics);
layer.active = false;
}
/**
* 从背包字顶边中点连到气泡底边中点。
* @param bagNode 背包字块
* @param tip 格子锁气泡
*/
private _drawLine(bagNode: Node, tip: Node): void {
const layer = this._lineLayer;
const g = this._graphics;
if (!layer?.isValid || !g?.isValid) return;
const layerUt = layer.getComponent(UITransform);
if (!layerUt) return;
const bagUt = bagNode.getComponent(UITransform);
const tipUt = tip.getComponent(UITransform);
const bagHalfH = bagUt ? bagUt.contentSize.height * 0.5 * Math.abs(bagNode.worldScale.y) : 30;
const tipHalfH = tipUt ? tipUt.contentSize.height * 0.5 * Math.abs(tip.worldScale.y) : 20;
_bagWorld.set(bagNode.worldPosition.x, bagNode.worldPosition.y + bagHalfH + BAG_TOP_PAD, bagNode.worldPosition.z);
_tipWorld.set(tip.worldPosition.x, tip.worldPosition.y - tipHalfH - TIP_BOTTOM_PAD, tip.worldPosition.z);
layerUt.convertToNodeSpaceAR(_bagWorld, _fromLocal);
layerUt.convertToNodeSpaceAR(_tipWorld, _toLocal);
g.clear();
this._fillZebraDash(g, _fromLocal.x, _fromLocal.y, _toLocal.x, _toLocal.y);
layer.active = true;
layer.setSiblingIndex(layer.parent!.children.length - 1);
}
/**
* 黑白段交替实心绳:每段先画反色描边再画本色,深色/浅色底上都清晰。
* @param g Graphics
* @param x1 起点 x
* @param y1 起点 y
* @param x2 终点 x
* @param y2 终点 y
*/
private _fillZebraDash(g: Graphics, x1: number, y1: number, x2: number, y2: number): void {
const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);
if (len < 1) return;
const ux = dx / len;
const uy = dy / len;
let d = 0;
let useBlack = true;
while (d < len) {
const d1 = Math.min(d + DASH_LEN, len);
const fill = useBlack ? DASH_BLACK : DASH_WHITE;
const outline = useBlack ? DASH_WHITE : DASH_BLACK;
this._fillDashSeg(g, x1, y1, ux, uy, d, d1, DASH_HALF_W + DASH_OUTLINE_EXTRA, outline);
this._fillDashSeg(g, x1, y1, ux, uy, d, d1, DASH_HALF_W, fill);
d = d1;
useBlack = !useBlack;
}
}
/**
* 沿路径画一段实心矩形(比 stroke 短段更稳、更粗)。
* @param g Graphics
* @param x1 路径起点 x
* @param y1 路径起点 y
* @param ux 单位方向 x
* @param uy 单位方向 y
* @param d0 段起点路程
* @param d1 段终点路程
* @param halfW 半宽
* @param color 填充色
*/
private _fillDashSeg(g: Graphics, x1: number, y1: number, ux: number, uy: number, d0: number, d1: number, halfW: number, color: Color): void {
const ax = x1 + ux * d0;
const ay = y1 + uy * d0;
const bx = x1 + ux * d1;
const by = y1 + uy * d1;
const px = -uy * halfW;
const py = ux * halfW;
g.fillColor = color;
g.moveTo(ax + px, ay + py);
g.lineTo(bx + px, by + py);
g.lineTo(bx - px, by - py);
g.lineTo(ax - px, ay - py);
g.close();
g.fill();
}
}

@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "a7c3e91b-2d4f-4a8e-9b1c-6f0e8d5a3c27",
"files": [],
"subMetas": {},
"userData": {}
}

@ -87,10 +87,12 @@ import {
isEnemyMonsterWalkGrid,
} from '../map/MapPathQueries';
import { MapDragGuideHelper, type DragPlacementHint } from './MapDragGuideHelper';
import { AreaUnlockGuidePresenter } from './AreaUnlockGuidePresenter';
import { LevelUpTextFloater } from './GridUpgradeSpineEffect';
import { BattleAudio } from '../audio/BattleAudio';
import { BagTextDragDebugLog } from '../debug/BagTextDragDebugLog';
import { AiBattleBridge } from '../ai/bridge/AiBattleBridge';
import { AI_VIEW_LOCAL_CAMP } from '../ai/runtime/AiCampArea';
import { HeadIconManager } from '../../manager/HeadIconManager';
import 'db://assets/mx/extension/NodeDragExt';
@ -173,6 +175,8 @@ export class CocosBagBoardView {
private _prepType3DraggingIndex: number | null = null;
private _linePresenter = new DragPlaceLinePresenter();
private _rangePresenter = new AttackRangePreviewPresenter();
/** 背包可解锁地图区域时的连线 / 虚线框引导 */
private _unlockGuide = new AreaUnlockGuidePresenter();
private _activeDrag: {
grid: TextGrid;
source: DragSource;
@ -1274,6 +1278,7 @@ export class CocosBagBoardView {
this._pathFlow = pathFlow ?? null;
this._linePresenter.bind(this._lineNode);
this._rangePresenter.bind(rangeNode ?? null, mapRoot?.parent ?? null);
this._unlockGuide.bind(this._lineNode?.parent ?? mapRoot?.parent ?? null);
// 槽位下标与格子下标(gridN → N)一致,槽数按最大格子下标 + 1 分配(slot0 对应不到格子,保持空)
let maxLandIndex = 0;
@ -1437,6 +1442,7 @@ export class CocosBagBoardView {
} catch (e) {
console.log('[CocosBagBoardView] _clearDragGuide failed', String(e));
}
this._unlockGuide.unbind();
this._linePresenter.unbind();
this._rangePresenter.unbind();
this._pathFlow?.endDrag();
@ -3204,6 +3210,9 @@ export class CocosBagBoardView {
this._rebuildFromSession();
return;
}
if (this._unlockGuide.slotIndex === source.slotIndex) {
this._unlockGuide.clear();
}
} else if (source.kind === 'map') {
const mapIndex = this._resolveMapGridIndexForTextGrid(grid);
if (mapIndex == null) {
@ -4604,6 +4613,7 @@ if (weapon2Id === GRID_WEAPON2_ID) return true;
fromWorld?: Readonly<Vec3> | null,
): void {
if (!this._bagSession || !this._bagList) return;
this._unlockGuide.clear();
this._invalidatePlaceFlights();
this._clearTextSelect();
this._bagEntrancePlaying = playBagEntrance;
@ -4794,6 +4804,7 @@ if (weapon2Id === GRID_WEAPON2_ID) return true;
fromWorld?: Readonly<Vec3> | null,
): void {
if (!this._bagSession || !this._map) return;
this._unlockGuide.clear();
// 先作废飞行中的 drop 回调,再改盘面;否则 onAnimDone 会对新背包再 drop → 空槽
this._invalidatePlaceFlights();
if (this._deploySync && this._map.gridsInitialized) {
@ -5121,6 +5132,7 @@ if (weapon2Id === GRID_WEAPON2_ID) return true;
return;
}
this._clearAllCanUpgradeHints();
this._refreshAreaUnlockGuide();
if (!this._bagSession) return;
WeaponComposeConfigProvider.instance.load();
@ -5195,6 +5207,22 @@ if (weapon2Id === GRID_WEAPON2_ID) return true;
for (const g of this._mapGrids.values()) g.setSleepFx(false);
}
/** 背包有可解锁当前地图区域的字时,显示虚线框与连线 */
private _refreshAreaUnlockGuide(): void {
if (!this._bagSession || !this._map) {
this._unlockGuide.clear();
return;
}
this._unlockGuide.refresh({
bagSession: this._bagSession,
map: this._map,
campAreaId: AI_VIEW_LOCAL_CAMP,
slotGridAt: (slotIndex) => this._slotGrids.get(slotIndex) ?? null,
canDragSlot: (slotIndex) => this._land.stateOf(slotIndex) === TextListCellState.Open,
skip: this._activeDrag != null || this._bagEntrancePlaying || !this._canDrag(),
});
}
private _playBagUpgradeEffect(slotIndex: number): void {
BattleAudio.playUpgrade();
this._playLevelUpTextForBag(slotIndex);

@ -162,6 +162,8 @@ export class GPath {
static ShopSkillTitle(name: string | number) { return "shopSkillTitle/" + name; }
/**通用仙桃图标(icons/img/仙桃) */
static CommPeach() { return "img/仙桃"; }
/** 五行属性图标(icons/img/金|木|水|火|土) */
static ElementAttr(name: string) { return "img/" + name; }
/**障碍物 */
static ObstacleItem(name: string | number) { return "texture/摆放路障/" + name; }
/**障碍物预制体 */

@ -43,6 +43,8 @@ export class ResPkgBuilder {
{ name: mapPrefabName, bundle: B.BattleMap, path: 'prefab/地图/', type: Prefab },
{ name: '出怪口', bundle: B.BattleMap, path: 'prefab/障碍物/', type: Prefab },
{ name: 'levelUpText', bundle: B.BattleMap, path: 'prefab/障碍物/', type: Prefab },
/** 背包可解锁地图区域时的虚线高亮框 */
{ name: '引导虚线框', bundle: B.BattleMap, path: 'prefab/障碍物/', type: Prefab },
{ name: 'monsterTemplate', bundle: B.BattleGameMonster, path: PrefabPath, type: Prefab },
{ name: 'textGrid', bundle: B.BattleGame, path: PrefabPath, type: Prefab },
/** 地图区域解锁条件气泡 */

Loading…
Cancel
Save