feat: 接入通关弹窗

This commit is contained in:
richarjiang
2026-04-26 16:20:37 +08:00
parent f5732b46a5
commit 5074706115
52 changed files with 8064 additions and 540 deletions

View File

@@ -5,11 +5,13 @@ import { StorageManager } from 'db://assets/scripts/utils/StorageManager';
import { StaminaManager } from 'db://assets/scripts/utils/StaminaManager';
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
import { AuthManager } from 'db://assets/scripts/utils/AuthManager';
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
import { ShareManager } from 'db://assets/scripts/utils/ShareManager';
import { PassModal } from 'db://assets/prefabs/PassModal';
import { StaminaInfo } from 'db://assets/scripts/types/ApiTypes';
import { AchievementTitleManager } from 'db://assets/scripts/utils/AchievementTitleManager';
const { ccclass, property } = _decorator;
/**
@@ -152,6 +154,9 @@ export class PageLevel extends BaseView {
/** 通关弹窗实例 */
private _passModalNode: Node | null = null;
/** 本次通关弹窗使用的已通关数量 */
private _passModalCompletedLevelCount: number | null = null;
/** 是否处于分享挑战模式 */
private _isShareMode: boolean = false;
@@ -1149,15 +1154,25 @@ export class PageLevel extends BaseView {
private reportLevelCompleted(levelId: string, timeSpent: number): void {
if (!this._isShareMode) {
// 标记关卡为已通关(本地缓存),通关上报并行执行,不阻塞包袱展示节奏
const wasCompleted = LevelDataManager.instance.isLevelCompleted(this.currentLevelIndex);
if (!wasCompleted) {
AuthManager.instance.addCompletedLevelCount();
}
this._passModalCompletedLevelCount = AuthManager.instance.completedLevelCount;
LevelDataManager.instance.markLevelCompleted(this.currentLevelIndex);
void StaminaManager.instance.completeLevel(levelId, timeSpent).then((result) => {
if (result) {
if (!result.firstClear && !wasCompleted) {
AuthManager.instance.addCompletedLevelCount(-1);
this._passModalCompletedLevelCount = AuthManager.instance.completedLevelCount;
}
console.log(`[PageLevel] 通关上报成功,首次通关: ${result.firstClear}`);
}
});
return;
}
this._passModalCompletedLevelCount = null;
// fire-and-forget: errors are logged inside reportLevelProgress
void ShareManager.instance.reportLevelProgress(levelId, true, timeSpent);
}
@@ -1199,7 +1214,10 @@ export class PageLevel extends BaseView {
// 获取 PassModal 组件并设置回调
const passModal = modalNode.getComponent(PassModal);
if (passModal) {
passModal.setParams({ levelIndex: this.currentLevelIndex + 1 });
passModal.setParams({
levelIndex: this.currentLevelIndex + 1,
titleInfo: AchievementTitleManager.getTitleInfo(this._getPassModalCompletedLevelCount())
});
passModal.setCallbacks({
onNextLevel: () => {
this._closePassModal();
@@ -1218,6 +1236,10 @@ export class PageLevel extends BaseView {
console.log('[PageLevel] 显示通关弹窗');
}
private _getPassModalCompletedLevelCount(): number {
return this._passModalCompletedLevelCount ?? AuthManager.instance.completedLevelCount;
}
/**
* 关闭通关弹窗
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
import { _decorator, Node, Label, AudioClip, AudioSource, view, UITransform, Size } from 'cc';
import { BaseView } from 'db://assets/scripts/core/BaseView';
import { _decorator, Node, Label, AudioClip, AudioSource, view, UITransform, Size, ProgressBar } from 'cc';
import { BaseModal } from 'db://assets/scripts/core/BaseModal';
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
const { ccclass, property } = _decorator;
@@ -13,12 +13,23 @@ export interface PassModalCallbacks {
onShare?: () => void;
}
export interface PassModalTitleInfo {
titleText?: string;
nextTitleProgress?: number;
progressText?: string;
}
interface PassModalParams {
levelIndex?: number;
titleInfo?: PassModalTitleInfo;
}
/**
* 通关弹窗组件
* 继承 BaseView,显示通关成功弹窗,提供"下一关"和"分享给好友"两个按钮
* 继承 BaseModal,显示通关成功弹窗,提供"下一关"和"分享给好友"两个按钮
*/
@ccclass('PassModal')
export class PassModal extends BaseView {
export class PassModal extends BaseModal {
/** 静态常量:弹窗层级 */
public static readonly MODAL_Z_INDEX = 999;
@@ -30,9 +41,17 @@ export class PassModal extends BaseView {
@property(Node)
shareButton: Node | null = null;
/** 提示Label如 恭喜通关) */
/** 称号文字 */
@property(Label)
tipLabel: Label | null = null;
titleLevelLabel: Label | null = null;
/** 距离下一个称号的进度 */
@property(ProgressBar)
titleProgressBar: ProgressBar | null = null;
/** 进度提示文案 */
@property(Label)
progressLabel: Label | null = null;
/** 通关音效 */
@property(AudioClip)
@@ -44,6 +63,21 @@ export class PassModal extends BaseView {
/** 缓存的屏幕尺寸 */
private _screenSize: Size | null = null;
/** 称号展示数据 */
private _titleInfo: PassModalTitleInfo = {
titleText: '冷场小白1级',
nextTitleProgress: 0,
progressText: '还差3题获得冷场小白2级'
};
setParams(params: PassModalParams): void {
super.setParams(params);
if (params?.titleInfo) {
this.setTitleInfo(params.titleInfo);
}
}
/**
* 设置回调函数
*/
@@ -51,6 +85,17 @@ export class PassModal extends BaseView {
this._callbacks = callbacks;
}
/**
* 设置称号体系展示数据
*/
setTitleInfo(titleInfo: PassModalTitleInfo): void {
this._titleInfo = {
...this._titleInfo,
...titleInfo
};
this._updateTitleInfo();
}
/**
* 页面首次加载时调用
*/
@@ -63,7 +108,9 @@ export class PassModal extends BaseView {
* 页面每次显示时调用
*/
onViewShow(): void {
super.onViewShow();
this._updateWidget();
this._updateTitleInfo();
this._playSuccessSound();
}
@@ -129,6 +176,34 @@ export class PassModal extends BaseView {
}
}
/**
* 更新称号体系核心变量
*/
private _updateTitleInfo(): void {
if (this.titleLevelLabel && this._titleInfo.titleText !== undefined) {
this.titleLevelLabel.string = this._titleInfo.titleText;
}
if (this.titleProgressBar && this._titleInfo.nextTitleProgress !== undefined) {
this.titleProgressBar.progress = this._normalizeProgress(this._titleInfo.nextTitleProgress);
}
if (this.progressLabel && this._titleInfo.progressText !== undefined) {
this.progressLabel.string = this._titleInfo.progressText;
}
}
/**
* 规范化进度值
*/
private _normalizeProgress(progress: number): number {
if (!Number.isFinite(progress)) {
return 0;
}
return Math.max(0, Math.min(1, progress));
}
/**
* 下一关按钮点击
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "e41c722f-f605-47f7-9ce4-abff0ed2020f",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "TimeoutModal"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "455c7845-d090-4cd9-aeb4-1f5cad616bb5",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "WrongModal"
}
}