feat: 支持关卡配置分享
This commit is contained in:
@@ -7,6 +7,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 { ShareManager } from 'db://assets/scripts/utils/ShareManager';
|
||||
import { PassModal } from 'db://assets/prefabs/PassModal';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -104,14 +105,26 @@ export class PageLevel extends BaseView {
|
||||
/** 通关弹窗实例 */
|
||||
private _passModalNode: Node | null = null;
|
||||
|
||||
/** 是否处于分享挑战模式 */
|
||||
private _isShareMode: boolean = false;
|
||||
|
||||
/**
|
||||
* 页面首次加载时调用
|
||||
*/
|
||||
onViewLoad(): void {
|
||||
console.log('[PageLevel] onViewLoad');
|
||||
// 从本地存储恢复关卡进度
|
||||
this.currentLevelIndex = StorageManager.getCurrentLevelIndex();
|
||||
console.log(`[PageLevel] 恢复关卡进度: 第 ${this.currentLevelIndex + 1} 关`);
|
||||
|
||||
const params = this.getParams();
|
||||
this._isShareMode = params?.shareMode === true;
|
||||
|
||||
if (this._isShareMode) {
|
||||
this.currentLevelIndex = 0;
|
||||
console.log('[PageLevel] 进入分享挑战模式');
|
||||
} else {
|
||||
// 从本地存储恢复关卡进度
|
||||
this.currentLevelIndex = StorageManager.getCurrentLevelIndex();
|
||||
console.log(`[PageLevel] 恢复关卡进度: 第 ${this.currentLevelIndex + 1} 关`);
|
||||
}
|
||||
this.updatePointsLabel();
|
||||
this.initIconSetting();
|
||||
this.initUnlockButtons();
|
||||
@@ -160,13 +173,18 @@ export class PageLevel extends BaseView {
|
||||
* 初始化关卡(从 API 数据加载,异步确保资源就绪)
|
||||
*/
|
||||
private async initLevel(): Promise<void> {
|
||||
// 先尝试从缓存获取
|
||||
let config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
|
||||
let config: RuntimeLevelConfig | null = null;
|
||||
|
||||
if (!config) {
|
||||
// 缓存中没有,异步加载
|
||||
console.log(`[PageLevel] 关卡 ${this.currentLevelIndex + 1} 资源未缓存,开始加载...`);
|
||||
config = await LevelDataManager.instance.ensureLevelReady(this.currentLevelIndex);
|
||||
if (this._isShareMode) {
|
||||
// 分享模式:从 ShareManager 获取关卡
|
||||
config = await ShareManager.instance.ensureShareLevelReady(this.currentLevelIndex);
|
||||
} else {
|
||||
// 正常模式:先尝试缓存,再异步加载
|
||||
config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
|
||||
if (!config) {
|
||||
console.log(`[PageLevel] 关卡 ${this.currentLevelIndex + 1} 资源未缓存,开始加载...`);
|
||||
config = await LevelDataManager.instance.ensureLevelReady(this.currentLevelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
@@ -212,7 +230,14 @@ export class PageLevel extends BaseView {
|
||||
this.updateClockLabel();
|
||||
|
||||
// 预加载下一关图片(静默加载,不阻塞)
|
||||
LevelDataManager.instance.preloadNextLevel(this.currentLevelIndex);
|
||||
if (this._isShareMode) {
|
||||
const nextIndex = this.currentLevelIndex + 1;
|
||||
if (nextIndex < ShareManager.instance.getShareLevelCount()) {
|
||||
ShareManager.instance.ensureShareLevelReady(nextIndex).catch(() => {});
|
||||
}
|
||||
} else {
|
||||
LevelDataManager.instance.preloadNextLevel(this.currentLevelIndex);
|
||||
}
|
||||
|
||||
console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}, 答案长度: ${config.answer.length}`);
|
||||
}
|
||||
@@ -356,7 +381,14 @@ export class PageLevel extends BaseView {
|
||||
private onIconSettingClick(): void {
|
||||
console.log('[PageLevel] IconSetting 点击,返回主页');
|
||||
this.playClickSound();
|
||||
ViewManager.instance.back();
|
||||
|
||||
// 分享模式下栈中没有 PageHome,需要清除分享状态并直接打开首页
|
||||
if (this._isShareMode) {
|
||||
ShareManager.instance.clearShareMode();
|
||||
ViewManager.instance.replace('PageHome');
|
||||
} else {
|
||||
ViewManager.instance.back();
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 线索相关方法 ==========
|
||||
@@ -656,10 +688,12 @@ export class PageLevel extends BaseView {
|
||||
// 播放成功音效
|
||||
this.playSuccessSound();
|
||||
|
||||
// 通关奖励:通过服务端增加积分
|
||||
const levelId = this._currentConfig?.id ?? '';
|
||||
await UserAssetsManager.instance.earnPoint(levelId);
|
||||
this.updatePointsLabel();
|
||||
// 通关奖励:分享模式下不增加积分
|
||||
if (!this._isShareMode) {
|
||||
const levelId = this._currentConfig?.id ?? '';
|
||||
await UserAssetsManager.instance.earnPoint(levelId);
|
||||
this.updatePointsLabel();
|
||||
}
|
||||
|
||||
// 显示通关弹窗
|
||||
this._showPassModal();
|
||||
@@ -748,19 +782,29 @@ export class PageLevel extends BaseView {
|
||||
* 进入下一关
|
||||
*/
|
||||
private async nextLevel(): Promise<void> {
|
||||
// 保存当前关卡进度
|
||||
StorageManager.onLevelCompleted(this.currentLevelIndex);
|
||||
// 分享模式不保存本地进度
|
||||
if (!this._isShareMode) {
|
||||
StorageManager.onLevelCompleted(this.currentLevelIndex);
|
||||
}
|
||||
|
||||
this.currentLevelIndex++;
|
||||
|
||||
// 检查是否还有关卡
|
||||
const totalLevels = LevelDataManager.instance.getLevelCount();
|
||||
const totalLevels = this._isShareMode
|
||||
? ShareManager.instance.getShareLevelCount()
|
||||
: LevelDataManager.instance.getLevelCount();
|
||||
|
||||
if (this.currentLevelIndex >= totalLevels) {
|
||||
// 所有关卡完成
|
||||
console.log('[PageLevel] 恭喜通关!');
|
||||
this.stopCountdown();
|
||||
ViewManager.instance.back();
|
||||
|
||||
if (this._isShareMode) {
|
||||
ShareManager.instance.clearShareMode();
|
||||
ViewManager.instance.replace('PageHome');
|
||||
} else {
|
||||
ViewManager.instance.back();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { BaseView } from 'db://assets/scripts/core/BaseView';
|
||||
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
|
||||
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
|
||||
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
|
||||
import { ShareManager } from 'db://assets/scripts/utils/ShareManager';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
@@ -78,6 +79,9 @@ export class PageWriteLevels extends BaseView {
|
||||
/** 缓存 view 节点的 UITransform,避免每次 _updateContentSize 重复查找 */
|
||||
private _viewTransform: UITransform | null = null;
|
||||
|
||||
/** 防止重复提交 */
|
||||
private _isSubmitting: boolean = false;
|
||||
|
||||
onViewLoad(): void {
|
||||
console.log('[PageWriteLevels] onViewLoad');
|
||||
this._initButtons();
|
||||
@@ -92,6 +96,9 @@ export class PageWriteLevels extends BaseView {
|
||||
if (this.previewBtn) {
|
||||
this.previewBtn.on(Button.EventType.CLICK, this._onPreviewClick, this);
|
||||
}
|
||||
if (this.completeBtn) {
|
||||
this.completeBtn.on(Button.EventType.CLICK, this._onCompleteClick, this);
|
||||
}
|
||||
}
|
||||
|
||||
private _initScrollView(): void {
|
||||
@@ -156,7 +163,10 @@ export class PageWriteLevels extends BaseView {
|
||||
|
||||
onViewShow(): void {
|
||||
console.log('[PageWriteLevels] onViewShow');
|
||||
this._initLevelList();
|
||||
// 仅首次初始化列表,从预览页返回时保留选中状态
|
||||
if (this._itemNodes.length === 0) {
|
||||
this._initLevelList();
|
||||
}
|
||||
}
|
||||
|
||||
private _initLevelList(): void {
|
||||
@@ -276,6 +286,8 @@ export class PageWriteLevels extends BaseView {
|
||||
const toggle = isSelected.getComponent(Toggle);
|
||||
if (toggle) {
|
||||
toggle.isChecked = this._selectedIndices.has(index);
|
||||
// 禁用 Toggle 交互,仅作为视觉指示器,选中逻辑由 item Button 统一处理
|
||||
toggle.interactable = false;
|
||||
}
|
||||
const checkmark = isSelected.getChildByName('Checkmark');
|
||||
if (checkmark) {
|
||||
@@ -428,14 +440,22 @@ export class PageWriteLevels extends BaseView {
|
||||
ViewManager.instance.back();
|
||||
}
|
||||
|
||||
private _onPreviewClick(): void {
|
||||
/**
|
||||
* 校验是否已选满关卡,未满则 Toast 提示
|
||||
* @returns true 表示校验通过
|
||||
*/
|
||||
private _validateSelection(): boolean {
|
||||
if (this._selectedIndices.size < MAX_SELECTION) {
|
||||
const remaining = MAX_SELECTION - this._selectedIndices.size;
|
||||
ToastManager.instance.show(`还需选择${remaining}个关卡`);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _onPreviewClick(): void {
|
||||
if (!this._validateSelection()) return;
|
||||
const shareTitle = this.shareTitleEditBox?.getComponent(EditBox)?.string?.trim() || '';
|
||||
console.log('[PageWriteLevels] 预览按钮点击,标题:', shareTitle, '已选关卡:', Array.from(this._selectedIndices));
|
||||
ViewManager.instance.open('PagePreviewLevels', {
|
||||
params: {
|
||||
selectedIndices: Array.from(this._selectedIndices),
|
||||
@@ -444,6 +464,57 @@ export class PageWriteLevels extends BaseView {
|
||||
});
|
||||
}
|
||||
|
||||
private async _onCompleteClick(): Promise<void> {
|
||||
if (!this._validateSelection()) return;
|
||||
|
||||
const shareTitle = this.shareTitleEditBox?.getComponent(EditBox)?.string?.trim() || '';
|
||||
if (!shareTitle) {
|
||||
ToastManager.instance.show('请输入分享标题');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isSubmitting) return;
|
||||
this._isSubmitting = true;
|
||||
|
||||
try {
|
||||
const levelIds = this._getSelectedLevelIds();
|
||||
if (levelIds.length !== MAX_SELECTION) {
|
||||
ToastManager.instance.show('获取关卡数据失败,请重试');
|
||||
return;
|
||||
}
|
||||
|
||||
const shareCode = await ShareManager.instance.createShare(shareTitle, levelIds);
|
||||
if (!shareCode) {
|
||||
ToastManager.instance.show('创建分享失败,请重试');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[PageWriteLevels] 创建分享成功, code:', shareCode);
|
||||
ShareManager.instance.triggerWxShare(shareTitle, shareCode);
|
||||
ToastManager.instance.show('分享创建成功!');
|
||||
} catch (err) {
|
||||
console.error('[PageWriteLevels] 完成按钮异常:', err);
|
||||
ToastManager.instance.show('操作失败,请重试');
|
||||
} finally {
|
||||
this._isSubmitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将选中的关卡索引转换为关卡 ID 数组
|
||||
*/
|
||||
private _getSelectedLevelIds(): string[] {
|
||||
const ids: string[] = [];
|
||||
const sortedIndices = Array.from(this._selectedIndices).sort((a, b) => a - b);
|
||||
for (const index of sortedIndices) {
|
||||
const config = LevelDataManager.instance.getLevelConfig(index);
|
||||
if (config) {
|
||||
ids.push(config.id);
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
onViewHide(): void {
|
||||
console.log('[PageWriteLevels] onViewHide');
|
||||
}
|
||||
@@ -456,6 +527,9 @@ export class PageWriteLevels extends BaseView {
|
||||
if (this.previewBtn) {
|
||||
this.previewBtn.off(Button.EventType.CLICK, this._onPreviewClick, this);
|
||||
}
|
||||
if (this.completeBtn) {
|
||||
this.completeBtn.off(Button.EventType.CLICK, this._onCompleteClick, this);
|
||||
}
|
||||
if (this.scrollView) {
|
||||
this.scrollView.off(Node.EventType.TOUCH_START, this._onTouchStart, this);
|
||||
this.scrollView.off(Node.EventType.TOUCH_END, this._onTouchEnd, this);
|
||||
|
||||
Reference in New Issue
Block a user