From 3c005d94a3bf55b51f7499ed205aa222d7104cc4 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Thu, 7 May 2026 19:54:05 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=80=9A=E5=85=B3?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/prefabs/PageLevel.prefab | 16 ++++---- assets/prefabs/PageLevel.ts | 67 ++++++++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/assets/prefabs/PageLevel.prefab b/assets/prefabs/PageLevel.prefab index 759a77a..d57ee0b 100644 --- a/assets/prefabs/PageLevel.prefab +++ b/assets/prefabs/PageLevel.prefab @@ -290,7 +290,7 @@ "_lpos": { "__type__": "cc.Vec3", "x": 0, - "y": 922.9949999999999, + "y": 848.5140000000001, "z": 0 }, "_lrot": { @@ -567,7 +567,7 @@ "_target": null, "_left": 0, "_right": 0, - "_top": 84.55500000000006, + "_top": 159.03599999999994, "_bottom": 0, "_horizontalCenter": 0, "_verticalCenter": 0, @@ -2064,8 +2064,8 @@ }, "_lpos": { "__type__": "cc.Vec3", - "x": -406.853, - "y": 811.433, + "x": -304.946, + "y": 963.458, "z": 0 }, "_lrot": { @@ -2567,9 +2567,9 @@ }, "_alignFlags": 9, "_target": null, - "_left": 83.14699999999999, + "_left": 185.05399999999997, "_right": 0, - "_top": 218.567, + "_top": 66.54200000000003, "_bottom": 0, "_horizontalCenter": 0, "_verticalCenter": 0, @@ -2636,7 +2636,7 @@ "_lpos": { "__type__": "cc.Vec3", "x": 303.639, - "y": 811.491, + "y": 963.516, "z": 0 }, "_lrot": { @@ -3140,7 +3140,7 @@ "_target": null, "_left": 0, "_right": 186.361, - "_top": 218.50900000000001, + "_top": 66.48400000000004, "_bottom": 0, "_horizontalCenter": 0, "_verticalCenter": 0, diff --git a/assets/prefabs/PageLevel.ts b/assets/prefabs/PageLevel.ts index 7aebbf0..0ef1255 100644 --- a/assets/prefabs/PageLevel.ts +++ b/assets/prefabs/PageLevel.ts @@ -1293,13 +1293,6 @@ export class PageLevel extends BaseView { this.playSound(this.clickAudio); } - /** - * 播放成功音效 - */ - private playSuccessSound(): void { - this.playSound(this.successAudio); - } - /** * 播放失败音效 */ @@ -1536,8 +1529,8 @@ export class PageLevel extends BaseView { // 停止倒计时 this.stopCountdown(); - // 播放成功音效 - this.playSuccessSound(); + // 通关音效不在这里播,改由通关弹窗 onViewShow 触发(见 PassModal._playSuccessSound) + // 产品节奏:玩家看到弹窗的瞬间音效才响起,避免谐音梗揭示期间就被音效抢戏 const punchline = this.getValidPunchline(this._currentConfig?.punchline ?? null); if (punchline) { @@ -1591,6 +1584,9 @@ export class PageLevel extends BaseView { this._passModalPreviousCompletedLevelCount = null; } console.log(`[PageLevel] 通关上报成功,首次通关: ${result.firstClear}, 有下一关: ${!!result.nextLevel}`); + + // 若此时通关弹窗已打开但当时 nextLevel 还没到,补一次底图预替换 + this._swapToNextLevelImagesIfReady(); } }); return; @@ -1668,6 +1664,10 @@ export class PageLevel extends BaseView { passModal.onViewShow(); } + // 弹窗已全屏遮盖当前关卡,利用这个时机把底层图片静默替换为下一关 + // 这样用户点"下一关"关闭弹窗时,底图已经是新的,不会出现闪烁 + this._swapToNextLevelImagesIfReady(); + console.log('[PageLevel] 显示通关弹窗'); } @@ -1675,6 +1675,55 @@ export class PageLevel extends BaseView { return this._passModalCompletedLevelCount ?? AuthManager.instance.completedLevelCount; } + /** + * 在通关弹窗遮盖期间,把底层的主图预先替换为下一关的图 + * 目的:点击"下一关"关闭弹窗的瞬间,底图已经是新的,避免闪屏 + * + * 三种情况: + * - 分享模式:直接通过 ShareManager.ensureShareLevelReady(index+1) 取下一关 config + * - 正常模式 & nextLevel 已到达:从 LevelDataManager 缓存里取(enter 时已 preloadLevel 过) + * - 正常模式 & nextLevel 尚未到达(complete 接口还没回包):由 reportLevelCompleted 的回调补偿调用 + */ + private _swapToNextLevelImagesIfReady(): void { + if (this._isShareMode) { + const nextIndex = this._shareLevelIndex + 1; + if (nextIndex >= ShareManager.instance.getShareLevelCount()) { + return; + } + // ensureShareLevelReady 若已缓存会立即 resolve;首次则会加载(此时图已在弹窗后面偷偷替换,用户无感) + ShareManager.instance.ensureShareLevelReady(nextIndex) + .then(config => this._applyNextLevelImagesFromConfig(config)) + .catch(() => {}); + return; + } + + const nextLevel = this._nextLevelData ?? AuthManager.instance.nextLevel; + if (!nextLevel) { + // complete 接口还没回包,走回调补偿路径 + return; + } + + const config = LevelDataManager.instance.getLevelConfig(nextLevel.id); + this._applyNextLevelImagesFromConfig(config); + } + + private _applyNextLevelImagesFromConfig(config: RuntimeLevelConfig | null): void { + if (!config) return; + + // 只在弹窗仍然打开时换图;否则说明用户已经点过下一关进入后续流程了,不再重复设置 + if (!this._passModalNode || !this._passModalNode.isValid) { + return; + } + + if (config.spriteFrame1) { + this.setMainImage(config.spriteFrame1); + } + if (config.spriteFrame2) { + this.setMainImage2(config.spriteFrame2); + } + console.log('[PageLevel] 弹窗遮盖期间已预替换下一关底图'); + } + /** * 关闭通关弹窗 */