feat: 支持通关弹窗

This commit is contained in:
richarjiang
2026-03-16 22:16:26 +08:00
parent 9899f696b2
commit a62eb2319c
5 changed files with 385 additions and 112 deletions

View File

@@ -1,4 +1,4 @@
import { _decorator, Node, EditBox, instantiate, Vec3, Button, Label, Sprite, SpriteFrame, AudioClip, AudioSource, UITransform } from 'cc';
import { _decorator, Node, EditBox, instantiate, Vec3, Button, Label, Sprite, SpriteFrame, AudioClip, AudioSource, UITransform, Prefab } from 'cc';
import { BaseView } from 'db://assets/scripts/core/BaseView';
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
import { StorageManager } from 'db://assets/scripts/utils/StorageManager';
@@ -6,6 +6,7 @@ import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
import { PassModal } from 'db://assets/prefabs/PassModal';
const { ccclass, property } = _decorator;
/**
@@ -14,6 +15,9 @@ const { ccclass, property } = _decorator;
*/
@ccclass('PageLevel')
export class PageLevel extends BaseView {
/** 静态常量:零位置 */
private static readonly ZERO_POS = new Vec3(0, 0, 0);
// ========== 节点引用 ==========
@property(Node)
inputLayout: Node | null = null;
@@ -73,6 +77,9 @@ export class PageLevel extends BaseView {
@property(AudioClip)
failAudio: AudioClip | null = null;
@property(Prefab)
passModalPrefab: Prefab | null = null;
// ========== 内部状态 ==========
/** 当前创建的输入框节点数组 */
private _inputNodes: Node[] = [];
@@ -89,6 +96,9 @@ export class PageLevel extends BaseView {
/** 是否正在切换关卡(防止重复提交) */
private _isTransitioning: boolean = false;
/** 通关弹窗实例 */
private _passModalNode: Node | null = null;
/**
* 页面首次加载时调用
*/
@@ -132,6 +142,7 @@ export class PageLevel extends BaseView {
console.log('[PageLevel] onViewDestroy');
this.clearInputNodes();
this.stopCountdown();
this._closePassModal();
}
/**
@@ -217,7 +228,7 @@ export class PageLevel extends BaseView {
inputNode.name = 'singleInput';
// 设置位置
inputNode.setPosition(new Vec3(0, 0, 0));
inputNode.setPosition(PageLevel.ZERO_POS);
// 获取 EditBox 组件
const editBox = inputNode.getComponent(EditBox);
@@ -664,10 +675,71 @@ export class PageLevel extends BaseView {
// 通关奖励:增加一颗生命值
this.addLife();
// 延迟后进入下一关
this.scheduleOnce(() => {
this.nextLevel();
}, 1.0);
// 显示通关弹窗
this._showPassModal();
}
/**
* 显示通关弹窗
* 将弹窗添加到 Canvas 根节点下(而非 PageLevel 子节点)
* 这样 Widget 可以正确对齐到全屏
*/
private _showPassModal(): void {
if (!this.passModalPrefab) {
console.warn('[PageLevel] passModalPrefab 未设置');
return;
}
// 如果弹窗已显示,不再重复创建
if (this._passModalNode && this._passModalNode.isValid) {
return;
}
// 实例化弹窗
const modalNode = instantiate(this.passModalPrefab);
modalNode.setPosition(PageLevel.ZERO_POS);
modalNode.setSiblingIndex(PassModal.MODAL_Z_INDEX);
// 找到 Canvas 根节点并添加弹窗
const canvasNode = this.node.parent;
if (canvasNode) {
canvasNode.addChild(modalNode);
} else {
this.node.addChild(modalNode);
}
this._passModalNode = modalNode;
// 获取 PassModal 组件并设置回调
const passModal = modalNode.getComponent(PassModal);
if (passModal) {
passModal.setParams({ levelIndex: this.currentLevelIndex + 1 });
passModal.setCallbacks({
onNextLevel: () => {
this._closePassModal();
this.nextLevel();
},
onShare: () => {
// 分享后不关闭弹窗,用户可继续点击下一关
console.log('[PageLevel] 分享完成');
}
});
// 手动调用 onViewLoad 和 onViewShow
passModal.onViewLoad();
passModal.onViewShow();
}
console.log('[PageLevel] 显示通关弹窗');
}
/**
* 关闭通关弹窗
*/
private _closePassModal(): void {
if (this._passModalNode && this._passModalNode.isValid) {
this._passModalNode.destroy();
this._passModalNode = null;
console.log('[PageLevel] 关闭通关弹窗');
}
}
/**