From c04a357183bd4b03df5c7397eb93941617bf0f7e Mon Sep 17 00:00:00 2001 From: pan Date: Fri, 11 Sep 2026 11:17:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=85=B3=E5=8D=A1?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E5=90=8C=E6=AD=A5=E7=B3=BB=E7=BB=9F=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96UI=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增GameEvent.STAGE_PROGRESS_UPDATE事件与关卡进度镜像逻辑 2. 在SingletonModuleComp中添加关卡进度VM层字段与同步方法 3. 重构MissionComp的UI显示逻辑,拆分计时与阶段显示 4. 更新mission.prefab的UI节点结构与数据绑定 5. 统一关卡进度更新的调用方式,替换直接赋值为专用方法 --- assets/resources/gui/element/mission.prefab | 728 +++++++++++++----- .../script/game/common/SingletonModuleComp.ts | 37 + assets/script/game/common/config/GameEvent.ts | 2 + assets/script/game/map/MissionComp.ts | 76 +- 4 files changed, 614 insertions(+), 229 deletions(-) diff --git a/assets/resources/gui/element/mission.prefab b/assets/resources/gui/element/mission.prefab index acac62e5..060d3fea 100644 --- a/assets/resources/gui/element/mission.prefab +++ b/assets/resources/gui/element/mission.prefab @@ -40,32 +40,32 @@ "_active": true, "_components": [ { - "__id__": 306 + "__id__": 324 }, { - "__id__": 308 + "__id__": 326 }, { - "__id__": 310 + "__id__": 328 }, { - "__id__": 312 + "__id__": 330 }, { - "__id__": 364 + "__id__": 382 }, { - "__id__": 366 + "__id__": 384 }, { - "__id__": 368 + "__id__": 386 }, { - "__id__": 370 + "__id__": 388 } ], "_prefab": { - "__id__": 372 + "__id__": 390 }, "_lpos": { "__type__": "cc.Vec3", @@ -5361,28 +5361,31 @@ "__id__": 263 }, { - "__id__": 279 + "__id__": 283 }, { - "__id__": 289 + "__id__": 293 } ], "_active": true, "_components": [ { - "__id__": 301 + "__id__": 317 }, { - "__id__": 303 + "__id__": 319 + }, + { + "__id__": 321 } ], "_prefab": { - "__id__": 305 + "__id__": 323 }, "_lpos": { "__type__": "cc.Vec3", - "x": 0, - "y": 1250, + "x": 230, + "y": 1110, "z": 0 }, "_lrot": { @@ -5421,22 +5424,22 @@ "__id__": 264 }, { - "__id__": 270 + "__id__": 272 } ], - "_active": false, + "_active": true, "_components": [ { - "__id__": 276 + "__id__": 280 } ], "_prefab": { - "__id__": 278 + "__id__": 282 }, "_lpos": { "__type__": "cc.Vec3", - "x": -259.716, - "y": 0, + "x": 0, + "y": 125, "z": 0 }, "_lrot": { @@ -5478,10 +5481,13 @@ }, { "__id__": 267 + }, + { + "__id__": 269 } ], "_prefab": { - "__id__": 269 + "__id__": 271 }, "_lpos": { "__type__": "cc.Vec3", @@ -5526,7 +5532,7 @@ }, "_contentSize": { "__type__": "cc.Size", - "width": 300, + "width": 400, "height": 98 }, "_anchorPoint": { @@ -5588,6 +5594,42 @@ "__type__": "cc.CompPrefabInfo", "fileId": "4cAcrNo5xOvoq1q9KeQ/zv" }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 264 + }, + "_enabled": true, + "__prefab": { + "__id__": 270 + }, + "_alignFlags": 40, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "76bjpP9QVJuYvQ1azsuWzZ" + }, { "__type__": "cc.PrefabInfo", "root": { @@ -5613,14 +5655,17 @@ "_active": true, "_components": [ { - "__id__": 271 + "__id__": 273 }, { - "__id__": 273 + "__id__": 275 + }, + { + "__id__": 277 } ], "_prefab": { - "__id__": 275 + "__id__": 279 }, "_lpos": { "__type__": "cc.Vec3", @@ -5657,11 +5702,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 270 + "__id__": 272 }, "_enabled": true, "__prefab": { - "__id__": 272 + "__id__": 274 }, "_contentSize": { "__type__": "cc.Size", @@ -5685,11 +5730,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 270 + "__id__": 272 }, "_enabled": true, "__prefab": { - "__id__": 274 + "__id__": 276 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -5701,10 +5746,10 @@ "b": 255, "a": 255 }, - "_string": "第 1 回合", + "_string": "第 {{0}}章{{0}}{{2}}关", "_horizontalAlign": 1, "_verticalAlign": 1, - "_actualFontSize": 26, + "_actualFontSize": 20, "_fontSize": 25, "_fontFamily": "Arial", "_lineHeight": 40, @@ -5747,6 +5792,32 @@ "__type__": "cc.CompPrefabInfo", "fileId": "8e+eoa74xGmoLxoLQGF8Ts" }, + { + "__type__": "545c05XsG9GDJispEGWKvYv", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 272 + }, + "_enabled": true, + "__prefab": { + "__id__": 278 + }, + "templateMode": true, + "watchPath": "", + "labelType": "cc.Label", + "watchPathArr": [ + "data.stage_progress.chapter ", + "data.stage_progress.stage", + "data.stage_progress.section" + ], + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "59fu9mvKBJt6F859wsFzEE" + }, { "__type__": "cc.PrefabInfo", "root": { @@ -5770,12 +5841,12 @@ }, "_enabled": true, "__prefab": { - "__id__": 277 + "__id__": 281 }, "_contentSize": { "__type__": "cc.Size", - "width": 100, - "height": 100 + "width": 200, + "height": 50 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -5811,17 +5882,17 @@ }, "_children": [ { - "__id__": 280 + "__id__": 284 } ], "_active": false, "_components": [ { - "__id__": 286 + "__id__": 290 } ], "_prefab": { - "__id__": 288 + "__id__": 292 }, "_lpos": { "__type__": "cc.Vec3", @@ -5858,20 +5929,20 @@ "_objFlags": 0, "__editorExtras__": {}, "_parent": { - "__id__": 279 + "__id__": 283 }, "_children": [], "_active": true, "_components": [ { - "__id__": 281 + "__id__": 285 }, { - "__id__": 283 + "__id__": 287 } ], "_prefab": { - "__id__": 285 + "__id__": 289 }, "_lpos": { "__type__": "cc.Vec3", @@ -5908,11 +5979,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 280 + "__id__": 284 }, "_enabled": true, "__prefab": { - "__id__": 282 + "__id__": 286 }, "_contentSize": { "__type__": "cc.Size", @@ -5936,11 +6007,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 280 + "__id__": 284 }, "_enabled": true, "__prefab": { - "__id__": 284 + "__id__": 288 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -6017,11 +6088,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 279 + "__id__": 283 }, "_enabled": true, "__prefab": { - "__id__": 287 + "__id__": 291 }, "_contentSize": { "__type__": "cc.Size", @@ -6062,25 +6133,31 @@ }, "_children": [ { - "__id__": 290 + "__id__": 294 + }, + { + "__id__": 302 } ], "_active": true, "_components": [ { - "__id__": 296 + "__id__": 310 }, { - "__id__": 298 + "__id__": 312 + }, + { + "__id__": 314 } ], "_prefab": { - "__id__": 300 + "__id__": 316 }, "_lpos": { "__type__": "cc.Vec3", - "x": 295.012, - "y": 0, + "x": 0, + "y": 75, "z": 0 }, "_lrot": { @@ -6108,28 +6185,31 @@ }, { "__type__": "cc.Node", - "_name": "Item_Hourglass_01_Gold", + "_name": "ItemIcon_Timer_Gold", "_objFlags": 0, "__editorExtras__": {}, "_parent": { - "__id__": 289 + "__id__": 293 }, "_children": [], "_active": true, "_components": [ { - "__id__": 291 + "__id__": 295 }, { - "__id__": 293 + "__id__": 297 + }, + { + "__id__": 299 } ], "_prefab": { - "__id__": 295 + "__id__": 301 }, "_lpos": { "__type__": "cc.Vec3", - "x": -61.674, + "x": -63.8, "y": 0, "z": 0 }, @@ -6142,8 +6222,8 @@ }, "_lscale": { "__type__": "cc.Vec3", - "x": 0.3, - "y": 0.3, + "x": 0.4, + "y": 0.4, "z": 1 }, "_mobility": 0, @@ -6162,11 +6242,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 290 + "__id__": 294 }, "_enabled": true, "__prefab": { - "__id__": 292 + "__id__": 296 }, "_contentSize": { "__type__": "cc.Size", @@ -6182,7 +6262,7 @@ }, { "__type__": "cc.CompPrefabInfo", - "fileId": "27ghZHS3tOFIh3ZpGiveVQ" + "fileId": "27Ueg4xqVCXKelT0xVtlj8" }, { "__type__": "cc.Sprite", @@ -6190,11 +6270,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 290 + "__id__": 294 }, "_enabled": true, "__prefab": { - "__id__": 294 + "__id__": 298 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -6222,15 +6302,48 @@ "_fillRange": 0, "_isTrimmedMode": true, "_useGrayscale": false, - "_atlas": { - "__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73", - "__expectedType__": "cc.SpriteAtlas" - }, + "_atlas": null, "_id": "" }, { "__type__": "cc.CompPrefabInfo", - "fileId": "ffEa9qjNFCzLb/BNiVx9XJ" + "fileId": "33vxrPOdBGO7bW7/xK7sh+" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 294 + }, + "_enabled": true, + "__prefab": { + "__id__": 300 + }, + "_alignFlags": 8, + "_target": null, + "_left": 15, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3bgVG50ahEKLPG9o3rzXol" }, { "__type__": "cc.PrefabInfo", @@ -6240,27 +6353,80 @@ "asset": { "__id__": 0 }, - "fileId": "a5AYYudYNH7JriPJUCohdF", + "fileId": "c5phsY7u9NKruBt8tkWdQK", "instance": null, "targetOverrides": null, "nestedPrefabInstanceRoots": null }, + { + "__type__": "cc.Node", + "_name": "Label", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 293 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 303 + }, + { + "__id__": 305 + }, + { + "__id__": 307 + } + ], + "_prefab": { + "__id__": 309 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 44.6923828125, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, { "__type__": "cc.UITransform", "_name": "", "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 289 + "__id__": 302 }, "_enabled": true, "__prefab": { - "__id__": 297 + "__id__": 304 }, "_contentSize": { "__type__": "cc.Size", - "width": 200, - "height": 54.4 + "width": 80.615234375, + "height": 50.4 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -6271,7 +6437,7 @@ }, { "__type__": "cc.CompPrefabInfo", - "fileId": "5bOKPX06JCgLYM3Izuo1rd" + "fileId": "36RSqOH4xB4L0DH9k0Yqnl" }, { "__type__": "cc.Label", @@ -6279,11 +6445,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 289 + "__id__": 302 }, "_enabled": true, "__prefab": { - "__id__": 299 + "__id__": 306 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -6298,21 +6464,21 @@ "_string": "30:00", "_horizontalAlign": 1, "_verticalAlign": 1, - "_actualFontSize": 26, + "_actualFontSize": 25, "_fontSize": 25, "_fontFamily": "Arial", "_lineHeight": 40, - "_overflow": 2, + "_overflow": 0, "_enableWrapText": true, "_font": null, "_isSystemFontUsed": true, "_spacingX": 0, "_isItalic": false, - "_isBold": true, + "_isBold": false, "_isUnderline": false, "_underlineHeight": 2, "_cacheMode": 0, - "_enableOutline": true, + "_enableOutline": false, "_outlineColor": { "__type__": "cc.Color", "r": 0, @@ -6339,7 +6505,158 @@ }, { "__type__": "cc.CompPrefabInfo", - "fileId": "4fhB8DvG9AE5pZw0e6V0Bc" + "fileId": "33eyBcUzBBCIZJYJ0208Sl" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 302 + }, + "_enabled": true, + "__prefab": { + "__id__": 308 + }, + "_alignFlags": 32, + "_target": null, + "_left": 0, + "_right": 15, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "93tA5TFb1Fr6yY0hVvTdYb" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "1aX99WFYVOHb3d/afJ8gHj", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 293 + }, + "_enabled": true, + "__prefab": { + "__id__": 311 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 200, + "height": 50 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "5bOKPX06JCgLYM3Izuo1rd" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 293 + }, + "_enabled": true, + "__prefab": { + "__id__": 313 + }, + "_alignFlags": 0, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "24igDyCpRK/pvGyEyh76bB" + }, + { + "__type__": "cc.Layout", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 293 + }, + "_enabled": false, + "__prefab": { + "__id__": 315 + }, + "_resizeMode": 0, + "_layoutType": 1, + "_cellSize": { + "__type__": "cc.Size", + "width": 40, + "height": 40 + }, + "_startAxis": 0, + "_paddingLeft": 0, + "_paddingRight": 0, + "_paddingTop": 0, + "_paddingBottom": 0, + "_spacingX": 0, + "_spacingY": 0, + "_verticalDirection": 1, + "_horizontalDirection": 0, + "_constraint": 0, + "_constraintNum": 2, + "_affectedByScale": false, + "_isAlign": false, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "aalY3IZFFJc7VGiWNfnvHS" }, { "__type__": "cc.PrefabInfo", @@ -6364,12 +6681,12 @@ }, "_enabled": true, "__prefab": { - "__id__": 302 + "__id__": 318 }, "_contentSize": { "__type__": "cc.Size", - "width": 720, - "height": 50 + "width": 200, + "height": 300 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -6392,13 +6709,13 @@ }, "_enabled": true, "__prefab": { - "__id__": 304 + "__id__": 320 }, - "_alignFlags": 41, + "_alignFlags": 33, "_target": null, - "_left": -1.2434497875801753e-14, - "_right": 1.2434497875801753e-14, - "_top": 5, + "_left": 310, + "_right": 30, + "_top": 20, "_bottom": 638.669, "_horizontalCenter": 0, "_verticalCenter": 0, @@ -6418,6 +6735,44 @@ "__type__": "cc.CompPrefabInfo", "fileId": "9e4Qf5jldBgoENlBF670t1" }, + { + "__type__": "cc.Layout", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 262 + }, + "_enabled": true, + "__prefab": { + "__id__": 322 + }, + "_resizeMode": 0, + "_layoutType": 2, + "_cellSize": { + "__type__": "cc.Size", + "width": 40, + "height": 40 + }, + "_startAxis": 0, + "_paddingLeft": 0, + "_paddingRight": 0, + "_paddingTop": 0, + "_paddingBottom": 0, + "_spacingX": 0, + "_spacingY": 0, + "_verticalDirection": 1, + "_horizontalDirection": 0, + "_constraint": 0, + "_constraintNum": 2, + "_affectedByScale": false, + "_isAlign": true, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "862VpUVzhABo1YOiA5qZND" + }, { "__type__": "cc.PrefabInfo", "root": { @@ -6441,7 +6796,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 307 + "__id__": 325 }, "_contentSize": { "__type__": "cc.Size", @@ -6469,7 +6824,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 309 + "__id__": 327 }, "_alignFlags": 21, "_target": null, @@ -6505,14 +6860,15 @@ }, "_enabled": true, "__prefab": { - "__id__": 311 + "__id__": 329 }, "debugMode": false, "showMemoryPanel": true, "start_btn": null, - "time_node": { - "__id__": 262 + "time_label": { + "__id__": 305 }, + "phase_label": null, "tooltip": { "__id__": 240 }, @@ -6532,7 +6888,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 313 + "__id__": 331 }, "cardPanNode": { "__id__": 131 @@ -6573,11 +6929,11 @@ "__id__": 159 }, "coins_node": { - "__id__": 314 + "__id__": 332 }, "hero_num_node": null, "refresh_stone_num_node": { - "__id__": 316 + "__id__": 334 }, "pickCountLabel": { "__id__": 142 @@ -6596,27 +6952,27 @@ "mountedRoot": null }, "_parent": { - "__id__": 315 + "__id__": 333 }, "_children": [ { - "__id__": 347 + "__id__": 365 }, { - "__id__": 353 + "__id__": 371 } ], "_active": false, "_components": [ { - "__id__": 359 + "__id__": 377 }, { - "__id__": 361 + "__id__": 379 } ], "_prefab": { - "__id__": 363 + "__id__": 381 }, "_lpos": { "__type__": "cc.Vec3", @@ -6657,29 +7013,29 @@ }, "_children": [ { - "__id__": 314 - }, - { - "__id__": 316 + "__id__": 332 }, { "__id__": 334 + }, + { + "__id__": 352 } ], "_active": true, "_components": [ { - "__id__": 340 + "__id__": 358 }, { - "__id__": 342 + "__id__": 360 }, { - "__id__": 344 + "__id__": 362 } ], "_prefab": { - "__id__": 346 + "__id__": 364 }, "_lpos": { "__type__": "cc.Vec3", @@ -6718,27 +7074,27 @@ "mountedRoot": null }, "_parent": { - "__id__": 315 + "__id__": 333 }, "_children": [ { - "__id__": 317 + "__id__": 335 }, { - "__id__": 323 + "__id__": 341 } ], "_active": true, "_components": [ { - "__id__": 329 + "__id__": 347 }, { - "__id__": 331 + "__id__": 349 } ], "_prefab": { - "__id__": 333 + "__id__": 351 }, "_lpos": { "__type__": "cc.Vec3", @@ -6775,20 +7131,20 @@ "_objFlags": 0, "__editorExtras__": {}, "_parent": { - "__id__": 316 + "__id__": 334 }, "_children": [], "_active": true, "_components": [ { - "__id__": 318 + "__id__": 336 }, { - "__id__": 320 + "__id__": 338 } ], "_prefab": { - "__id__": 322 + "__id__": 340 }, "_lpos": { "__type__": "cc.Vec3", @@ -6825,11 +7181,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 317 + "__id__": 335 }, "_enabled": true, "__prefab": { - "__id__": 319 + "__id__": 337 }, "_contentSize": { "__type__": "cc.Size", @@ -6853,11 +7209,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 317 + "__id__": 335 }, "_enabled": true, "__prefab": { - "__id__": 321 + "__id__": 339 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -6914,20 +7270,20 @@ "_objFlags": 0, "__editorExtras__": {}, "_parent": { - "__id__": 316 + "__id__": 334 }, "_children": [], "_active": true, "_components": [ { - "__id__": 324 + "__id__": 342 }, { - "__id__": 326 + "__id__": 344 } ], "_prefab": { - "__id__": 328 + "__id__": 346 }, "_lpos": { "__type__": "cc.Vec3", @@ -6964,11 +7320,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 323 + "__id__": 341 }, "_enabled": true, "__prefab": { - "__id__": 325 + "__id__": 343 }, "_contentSize": { "__type__": "cc.Size", @@ -6992,11 +7348,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 323 + "__id__": 341 }, "_enabled": true, "__prefab": { - "__id__": 327 + "__id__": 345 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -7073,11 +7429,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 316 + "__id__": 334 }, "_enabled": true, "__prefab": { - "__id__": 330 + "__id__": 348 }, "_contentSize": { "__type__": "cc.Size", @@ -7101,11 +7457,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 316 + "__id__": 334 }, "_enabled": true, "__prefab": { - "__id__": 332 + "__id__": 350 }, "_resizeMode": 1, "_layoutType": 1, @@ -7154,20 +7510,20 @@ "mountedRoot": null }, "_parent": { - "__id__": 315 + "__id__": 333 }, "_children": [], "_active": true, "_components": [ { - "__id__": 335 + "__id__": 353 }, { - "__id__": 337 + "__id__": 355 } ], "_prefab": { - "__id__": 339 + "__id__": 357 }, "_lpos": { "__type__": "cc.Vec3", @@ -7204,11 +7560,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 334 + "__id__": 352 }, "_enabled": true, "__prefab": { - "__id__": 336 + "__id__": 354 }, "_contentSize": { "__type__": "cc.Size", @@ -7232,11 +7588,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 334 + "__id__": 352 }, "_enabled": true, "__prefab": { - "__id__": 338 + "__id__": 356 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -7313,11 +7669,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 315 + "__id__": 333 }, "_enabled": true, "__prefab": { - "__id__": 341 + "__id__": 359 }, "_contentSize": { "__type__": "cc.Size", @@ -7341,11 +7697,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 315 + "__id__": 333 }, "_enabled": true, "__prefab": { - "__id__": 343 + "__id__": 361 }, "_alignFlags": 45, "_target": null, @@ -7377,11 +7733,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 315 + "__id__": 333 }, "_enabled": true, "__prefab": { - "__id__": 345 + "__id__": 363 }, "_resizeMode": 1, "_layoutType": 2, @@ -7428,20 +7784,20 @@ "_objFlags": 0, "__editorExtras__": {}, "_parent": { - "__id__": 314 + "__id__": 332 }, "_children": [], "_active": true, "_components": [ { - "__id__": 348 + "__id__": 366 }, { - "__id__": 350 + "__id__": 368 } ], "_prefab": { - "__id__": 352 + "__id__": 370 }, "_lpos": { "__type__": "cc.Vec3", @@ -7478,11 +7834,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 347 + "__id__": 365 }, "_enabled": true, "__prefab": { - "__id__": 349 + "__id__": 367 }, "_contentSize": { "__type__": "cc.Size", @@ -7506,11 +7862,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 347 + "__id__": 365 }, "_enabled": true, "__prefab": { - "__id__": 351 + "__id__": 369 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -7567,20 +7923,20 @@ "_objFlags": 0, "__editorExtras__": {}, "_parent": { - "__id__": 314 + "__id__": 332 }, "_children": [], "_active": true, "_components": [ { - "__id__": 354 + "__id__": 372 }, { - "__id__": 356 + "__id__": 374 } ], "_prefab": { - "__id__": 358 + "__id__": 376 }, "_lpos": { "__type__": "cc.Vec3", @@ -7617,11 +7973,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 353 + "__id__": 371 }, "_enabled": true, "__prefab": { - "__id__": 355 + "__id__": 373 }, "_contentSize": { "__type__": "cc.Size", @@ -7645,11 +8001,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 353 + "__id__": 371 }, "_enabled": true, "__prefab": { - "__id__": 357 + "__id__": 375 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -7726,11 +8082,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 314 + "__id__": 332 }, "_enabled": true, "__prefab": { - "__id__": 360 + "__id__": 378 }, "_contentSize": { "__type__": "cc.Size", @@ -7754,11 +8110,11 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 314 + "__id__": 332 }, "_enabled": true, "__prefab": { - "__id__": 362 + "__id__": 380 }, "_resizeMode": 1, "_layoutType": 1, @@ -7809,7 +8165,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 365 + "__id__": 383 }, "_id": "" }, @@ -7827,7 +8183,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 367 + "__id__": 385 }, "debugMode": false, "_id": "" @@ -7846,7 +8202,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 369 + "__id__": 387 }, "skill_box": { "__uuid__": "d19cde30-f5d0-47de-a0d5-3a272b696343", @@ -7868,7 +8224,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 371 + "__id__": 389 }, "equip_box": { "__uuid__": "66d7902d-2a85-43d5-8cbb-671cc7dbb275", @@ -7895,10 +8251,10 @@ "instance": null, "targetOverrides": [ { - "__id__": 373 + "__id__": 391 }, { - "__id__": 375 + "__id__": 393 } ], "nestedPrefabInstanceRoots": [ @@ -7916,7 +8272,7 @@ { "__type__": "cc.TargetOverrideInfo", "source": { - "__id__": 312 + "__id__": 330 }, "sourceInfo": null, "propertyPath": [ @@ -7926,7 +8282,7 @@ "__id__": 159 }, "targetInfo": { - "__id__": 374 + "__id__": 392 } }, { @@ -7938,7 +8294,7 @@ { "__type__": "cc.TargetOverrideInfo", "source": { - "__id__": 312 + "__id__": 330 }, "sourceInfo": null, "propertyPath": [ @@ -7948,7 +8304,7 @@ "__id__": 159 }, "targetInfo": { - "__id__": 376 + "__id__": 394 } }, { diff --git a/assets/script/game/common/SingletonModuleComp.ts b/assets/script/game/common/SingletonModuleComp.ts index e30721c3..5252448d 100644 --- a/assets/script/game/common/SingletonModuleComp.ts +++ b/assets/script/game/common/SingletonModuleComp.ts @@ -234,6 +234,12 @@ export class SingletonModuleComp extends ecs.Comp { silver: 0, // 银币数据(MVVM绑定字段,镜像 data.silver,刷新卡牌消耗) switch_effect: true, // 音效开关(MVVM绑定字段) switch_music: true, // 音乐开关(MVVM绑定字段) + /** 关卡进度(MVVM绑定字段,镜像 data.stage_progress,供 HUD 实时显示) */ + stage_progress: { + chapter: 1, + stage: 1, + section: 1, + }, }; @@ -325,7 +331,9 @@ export class SingletonModuleComp extends ecs.Comp { // 触发UI更新(同步镜像层 + 事件) this.syncCurrencyToView(); + this.syncStageProgressToView(); oops.message.dispatchEvent(GameEvent.GOLD_UPDATE); + oops.message.dispatchEvent(GameEvent.STAGE_PROGRESS_UPDATE); } catch (error) { mLogger.error(this.debugMode, 'SMC', `[SMC]: 数据覆盖失败:`, error); @@ -342,6 +350,35 @@ export class SingletonModuleComp extends ecs.Comp { this.vmdata.diamond = this.data.diamond ?? 0; this.vmdata.silver = this.data.silver ?? 0; } + + /** + * 将 data 层的关卡进度镜像到 vmdata 视图层(MVVM 绑定字段)。 + * Why: data.stage_progress 为云端持久权威源,vmdata.stage_progress 仅供 HUD 绑定展示; + * 登录覆盖、关卡推进后都必须调用本方法保持镜像一致。 + */ + public syncStageProgressToView(): void { + const p = this.data.stage_progress; + this.vmdata.stage_progress = { + chapter: p?.chapter ?? 1, + stage: p?.stage ?? 1, + section: p?.section ?? 1, + }; + } + + /** + * 更新关卡进度(权威源 data + 视图镜像 vmdata),并派发事件刷新 UI。 + * Why: 替代直接赋值 smc.data.stage_progress,保证视图层实时同步。 + * @param progress 新的关卡进度(章节/大关/小节均从 1 开始) + * @param is_sync 是否标记脏并触发云端/本地同步 + */ + public updateStageProgress(progress: { chapter: number; stage: number; section: number }, is_sync: boolean = true): void { + this.data.stage_progress = { ...progress }; + this.syncStageProgressToView(); + if (is_sync) { + gameDataSync.markDataDirty(); + } + oops.message.dispatchEvent(GameEvent.STAGE_PROGRESS_UPDATE); + } getGameDate() { let data: GameDate = { ...this.data, diff --git a/assets/script/game/common/config/GameEvent.ts b/assets/script/game/common/config/GameEvent.ts index 8407c171..2349b2f9 100644 --- a/assets/script/game/common/config/GameEvent.ts +++ b/assets/script/game/common/config/GameEvent.ts @@ -100,6 +100,8 @@ export enum GameEvent { HERO_GROWTH_UPDATE = "HERO_GROWTH_UPDATE", /** 天赋数据变更(等级/点数更新,payload 为空,UI 重新读取 smc.data.talents / talent_points) */ TALENT_UPDATE = "TALENT_UPDATE", + /** 关卡进度变更(payload 为空,UI 重新读取 smc.vmdata.stage_progress) */ + STAGE_PROGRESS_UPDATE = "STAGE_PROGRESS_UPDATE", /** 小节开始(payload: { chapter, stage, section },MissionMonComp 据此生成怪物) */ SectionStart = "SectionStart", /** 小节结束(payload: { chapter, stage, section },玩家点击"下一节"后推进) */ diff --git a/assets/script/game/map/MissionComp.ts b/assets/script/game/map/MissionComp.ts index 120ec472..d2512a2c 100644 --- a/assets/script/game/map/MissionComp.ts +++ b/assets/script/game/map/MissionComp.ts @@ -90,9 +90,12 @@ export class MissionComp extends CCComp { /** 开始战斗按钮 */ @property(Node) start_btn: Node = null! - /** 时间/回合数显示节点 */ - @property(Node) - time_node: Node = null! + /** 战斗计时 Label(mm:ss) */ + @property(Label) + time_label: Label = null! + /** 阶段/进度显示 Label("第 X 节" / 回合间倒计时) */ + @property(Label) + phase_label: Label = null! @property(Node) tooltip: Node = null! @@ -298,12 +301,8 @@ export class MissionComp extends CCComp { let s = remainSecond % 60; let str = `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; if (str != this.lastTimeStr) { - if (this.time_node && this.time_node.isValid) { - const timeChild = this.time_node.getChildByName("time"); - if (timeChild) { - const label = timeChild.getComponent(Label); - if (label) label.string = str; - } + if (this.time_label && this.time_label.isValid) { + this.time_label.string = str; } this.lastTimeStr = str; } @@ -332,14 +331,8 @@ export class MissionComp extends CCComp { if (!force && remain === this.lastTimeSecond) return; this.lastTimeSecond = remain; - if (this.time_node && this.time_node.isValid) { - const phaseNode = this.time_node.getChildByPath("Phase/Label"); - if (phaseNode) { - const label = phaseNode.getComponent(Label); - if (label) { - label.string = `下一节 ${remain}s`; - } - } + if (this.phase_label && this.phase_label.isValid) { + this.phase_label.string = `下一节 ${remain}s`; } } @@ -490,23 +483,18 @@ export class MissionComp extends CCComp { } // 更新阶段显示 UI - if (this.time_node && this.time_node.isValid) { - const phaseNode = this.time_node.getChildByPath("Phase/Label"); - if (phaseNode) { - const label = phaseNode.getComponent(Label); - if (label) { - label.string = `第 ${getProgressText(this.currentChapter, this.currentStage, this.currentSection)} 节`; - } + if (this.phase_label && this.phase_label.isValid) { + this.phase_label.string = `第 ${getProgressText(this.currentChapter, this.currentStage, this.currentSection)} 节`; - // 阶段切换动感表现:只在进入战斗阶段跳动一下,让流程充满心流体验 - if (targetPhase === MissionPhase.BattleStart) { - Tween.stopAllByTarget(this.time_node); - this.time_node.scale = v3(1, 1, 1); - tween(this.time_node) - .to(0.3, { scale: v3(1.2, 1.2, 1) }, { easing: "backOut" }) - .to(0.2, { scale: v3(1, 1, 1) }, { easing: "sineInOut" }) - .start(); - } + // 阶段切换动感表现:只在进入战斗阶段跳动一下,让流程充满心流体验 + if (targetPhase === MissionPhase.BattleStart) { + const labelNode = this.phase_label.node; + Tween.stopAllByTarget(labelNode); + labelNode.scale = v3(1, 1, 1); + tween(labelNode) + .to(0.3, { scale: v3(1.2, 1.2, 1) }, { easing: "backOut" }) + .to(0.2, { scale: v3(1, 1, 1) }, { easing: "sineInOut" }) + .start(); } } @@ -811,11 +799,11 @@ export class MissionComp extends CCComp { // 存档直接推进到下一关第 1 小节(仅写存档,内存进度保留用于本局结算显示); // 第 10 关通关即本章全通,存档停留等待后续章节扩展 if (this.currentStage < 10) { - smc.data.stage_progress = { + smc.updateStageProgress({ chapter: this.currentChapter, stage: this.currentStage + 1, section: 1, - }; + }); if ((smc as any).updateCloudData) { (smc as any).updateCloudData(); } @@ -921,20 +909,22 @@ export class MissionComp extends CCComp { this.currentStage = 1; this.currentSection = 1; } + // 加载完成后将权威进度镜像到 vmdata,驱动 HUD 实时显示 + smc.syncStageProgressToView(); mLogger.log(this.debugMode, 'MissionComp', `[StageProgress] 加载进度: ${getProgressText(this.currentChapter, this.currentStage, this.currentSection)}`); } /** * 保存关卡进度存档 - * 写入 smc.data.stage_progress,并标记云端同步 + * 写入 smc.data.stage_progress 并镜像到 vmdata,同时标记云端同步 */ private saveStageProgress() { - smc.data.stage_progress = { + smc.updateStageProgress({ chapter: this.currentChapter, stage: this.currentStage, section: this.currentSection, - }; + }); // 标记数据脏,触发云端/本地同步 if ((smc as any).updateCloudData) { (smc as any).updateCloudData(); @@ -1228,13 +1218,13 @@ export class MissionComp extends CCComp { /** 性能监控相关代码 */ - /** 初始化性能监控面板:在 time_node 下创建 Label */ + /** 初始化性能监控面板:在本组件节点下创建 Label */ private initMemoryPanel() { - if (!this.showMemoryPanel || !this.time_node) return; - let panel = this.time_node.getChildByName("mem_panel"); + if (!this.showMemoryPanel) return; + let panel = this.node.getChildByName("mem_panel"); if (!panel) { panel = new Node("mem_panel"); - panel.parent = this.time_node; + panel.parent = this.node; panel.setPosition(0, -32, 0); } let label = panel.getComponent(Label); @@ -1248,7 +1238,7 @@ export class MissionComp extends CCComp { /** 移除性能监控面板 */ private removeMemoryPanel() { - const panel = this.time_node?.getChildByName("mem_panel"); + const panel = this.node?.getChildByName("mem_panel"); if (panel) { panel.destroy(); }