feat: 接入关卡配置 API 并支持降级到本地配置

- 新增 LevelDataManager 单例管理关卡数据
- 新增 HttpUtil 封装 XMLHttpRequest 请求
- 新增 LevelTypes 类型定义
- PageLoading 集成 API 数据预加载(0-80% 进度)
- PageLevel 支持优先使用 API 数据,失败时降级到本地配置
- 字段映射: hint1/2/3 → clue1/2/3, imageUrl → SpriteFrame
This commit is contained in:
richarjiang
2026-03-15 16:07:00 +08:00
parent c9fbc5212a
commit c54a404c12
5 changed files with 430 additions and 18 deletions

View File

@@ -3,6 +3,8 @@ import { BaseView } from 'db://assets/scripts/core/BaseView';
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
import { StorageManager } from 'db://assets/scripts/utils/StorageManager';
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
const { ccclass, property } = _decorator;
/**
@@ -104,6 +106,9 @@ export class PageLevel extends BaseView {
/** 倒计时是否结束 */
private _isTimeUp: boolean = false;
/** 当前关卡配置API 或本地) */
private _currentConfig: RuntimeLevelConfig | null = null;
/**
* 页面首次加载时调用
*/
@@ -145,18 +150,67 @@ export class PageLevel extends BaseView {
* 初始化关卡
*/
private initLevel(): void {
const config = this.levelConfigs[this.currentLevelIndex];
// 优先使用 API 数据
if (LevelDataManager.instance.hasApiData()) {
this._initFromApiConfig();
} else {
this._initFromLocalConfig();
}
}
/**
* 从 API 配置初始化关卡
*/
private _initFromApiConfig(): void {
const config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
if (!config) {
console.warn('[PageLevel] 没有找到关卡配置');
console.warn('[PageLevel] 没有找到 API 关卡配置');
// 降级到本地配置
this._initFromLocalConfig();
return;
}
console.log(`[PageLevel] 使用 API 配置初始化关卡 ${this.currentLevelIndex + 1}: ${config.name}`);
this._applyLevelConfig(config);
}
/**
* 从本地配置初始化关卡
*/
private _initFromLocalConfig(): void {
const config = this.levelConfigs[this.currentLevelIndex];
if (!config) {
console.warn('[PageLevel] 没有找到本地关卡配置');
return;
}
// 创建 RuntimeLevelConfig 从本地配置
const runtimeConfig: RuntimeLevelConfig = {
id: this.currentLevelIndex,
name: `关卡 ${this.currentLevelIndex + 1}`,
spriteFrame: config.mainImage,
clue1: config.clue1,
clue2: config.clue2,
clue3: config.clue3,
answer: config.answer
};
console.log(`[PageLevel] 使用本地配置初始化关卡 ${this.currentLevelIndex + 1}`);
this._applyLevelConfig(runtimeConfig);
}
/**
* 应用关卡配置(通用初始化逻辑)
*/
private _applyLevelConfig(config: RuntimeLevelConfig): void {
this._currentConfig = config;
// 重置倒计时状态
this._isTimeUp = false;
this._countdown = 60;
// 设置主图
this.setMainImage(config.mainImage);
this.setMainImage(config.spriteFrame);
// 设置线索1默认解锁
this.setClue(1, config.clue1);
@@ -170,13 +224,12 @@ export class PageLevel extends BaseView {
this.showUnlockButton(3);
// 根据答案长度创建单个输入框
const answerLength = config.answer.length;
this.createSingleInput(answerLength);
this.createSingleInput(config.answer.length);
// 更新倒计时显示
this.updateClockLabel();
console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}, 答案长度: ${answerLength}`);
console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}, 答案长度: ${config.answer.length}`);
}
/**
@@ -455,9 +508,8 @@ export class PageLevel extends BaseView {
this.showClue(index);
// 设置线索内容
const config = this.levelConfigs[this.currentLevelIndex];
if (config) {
const clueContent = index === 2 ? config.clue2 : config.clue3;
if (this._currentConfig) {
const clueContent = index === 2 ? this._currentConfig.clue2 : this._currentConfig.clue3;
this.setClue(index, clueContent);
}
@@ -615,13 +667,12 @@ export class PageLevel extends BaseView {
* 提交答案
*/
onSubmitAnswer(): void {
const config = this.levelConfigs[this.currentLevelIndex];
if (!config) return;
if (!this._currentConfig) return;
const userAnswer = this.getAnswer();
console.log(`[PageLevel] 提交答案: ${userAnswer}, 正确答案: ${config.answer}`);
console.log(`[PageLevel] 提交答案: ${userAnswer}, 正确答案: ${this._currentConfig.answer}`);
if (userAnswer === config.answer) {
if (userAnswer === this._currentConfig.answer) {
// 答案正确
this.playClickSound();
this.showSuccess();
@@ -671,7 +722,13 @@ export class PageLevel extends BaseView {
private nextLevel(): void {
this.currentLevelIndex++;
if (this.currentLevelIndex >= this.levelConfigs.length) {
// 检查是否还有关卡
const manager = LevelDataManager.instance;
const totalLevels = manager.hasApiData()
? manager.getLevelCount()
: this.levelConfigs.length;
if (this.currentLevelIndex >= totalLevels) {
// 所有关卡完成
console.log('[PageLevel] 恭喜通关!');
this.stopCountdown();