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; /** * PassModal 回调接口 */ export interface PassModalCallbacks { /** 点击下一关回调 */ onNextLevel?: () => void; /** 点击分享回调 */ onShare?: () => void; } export interface PassModalTitleInfo { titleText?: string; nextTitleProgress?: number; progressText?: string; } interface PassModalParams { levelIndex?: number; titleInfo?: PassModalTitleInfo; } /** * 通关弹窗组件 * 继承 BaseModal,显示通关成功弹窗,提供"下一关"和"分享给好友"两个按钮 */ @ccclass('PassModal') export class PassModal extends BaseModal { /** 静态常量:弹窗层级 */ public static readonly MODAL_Z_INDEX = 999; /** 下一关按钮 */ @property(Node) nextLevelButton: Node | null = null; /** 分享按钮 */ @property(Node) shareButton: Node | null = null; /** 称号文字 */ @property(Label) titleLevelLabel: Label | null = null; /** 距离下一个称号的进度 */ @property(ProgressBar) titleProgressBar: ProgressBar | null = null; /** 进度提示文案 */ @property(Label) progressLabel: Label | null = null; /** 通关音效 */ @property(AudioClip) successAudio: AudioClip | null = null; /** 回调函数 */ private _callbacks: PassModalCallbacks = {}; /** 缓存的屏幕尺寸 */ 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); } } /** * 设置回调函数 */ setCallbacks(callbacks: PassModalCallbacks): void { this._callbacks = callbacks; } /** * 设置称号体系展示数据 */ setTitleInfo(titleInfo: PassModalTitleInfo): void { this._titleInfo = { ...this._titleInfo, ...titleInfo }; this._updateTitleInfo(); } /** * 页面首次加载时调用 */ onViewLoad(): void { console.log('[PassModal] onViewLoad'); this._bindButtonEvents(); } /** * 页面每次显示时调用 */ onViewShow(): void { super.onViewShow(); this._updateWidget(); this._updateTitleInfo(); this._playSuccessSound(); } /** * 页面销毁时调用 */ onViewDestroy(): void { this._unbindButtonEvents(); } /** * 设置弹窗尺寸为全屏 * 动态实例化后,手动设置节点尺寸覆盖整个屏幕 */ private _updateWidget(): void { // 缓存屏幕尺寸,避免重复计算 if (!this._screenSize) { this._screenSize = view.getVisibleSize(); } const uiTransform = this.node.getComponent(UITransform); if (uiTransform) { uiTransform.setContentSize(this._screenSize.width, this._screenSize.height); } } /** * 绑定按钮事件 */ private _bindButtonEvents(): void { if (this.nextLevelButton) { this.nextLevelButton.on(Node.EventType.TOUCH_END, this._onNextLevelClick, this); } if (this.shareButton) { this.shareButton.on(Node.EventType.TOUCH_END, this._onShareClick, this); } } /** * 解除按钮事件绑定 */ private _unbindButtonEvents(): void { // 节点可能在销毁过程中已被置空,需要检查 isValid if (this.nextLevelButton && this.nextLevelButton.isValid) { this.nextLevelButton.off(Node.EventType.TOUCH_END, this._onNextLevelClick, this); } if (this.shareButton && this.shareButton.isValid) { this.shareButton.off(Node.EventType.TOUCH_END, this._onShareClick, this); } } /** * 播放通关音效 */ private _playSuccessSound(): void { if (!this.successAudio) { return; } const audioSource = this.node.getComponent(AudioSource); if (audioSource) { audioSource.playOneShot(this.successAudio); } } /** * 更新称号体系核心变量 */ 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)); } /** * 下一关按钮点击 */ private _onNextLevelClick(): void { console.log('[PassModal] 点击下一关'); this._callbacks.onNextLevel?.(); } /** * 分享按钮点击 */ private _onShareClick(): void { console.log('[PassModal] 点击分享'); // 调用微信分享 WxSDK.shareAppMessage({ title: '快来一起玩这款游戏吧', query: `level=${this._params?.levelIndex ?? 1}` }); this._callbacks.onShare?.(); } }