feat: 支持关卡数据

This commit is contained in:
richarjiang
2026-03-15 23:12:06 +08:00
parent c54a404c12
commit 9ec8106733
8 changed files with 1246 additions and 1291 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -7,27 +7,6 @@ import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
const { ccclass, property } = _decorator;
/**
* 关卡配置类
*/
@ccclass('LevelConfig')
export class LevelConfig {
@property(SpriteFrame)
mainImage: SpriteFrame | null = null;
@property({ tooltip: '线索1内容默认解锁' })
clue1: string = '';
@property({ tooltip: '线索2内容' })
clue2: string = '';
@property({ tooltip: '线索3内容' })
clue3: string = '';
@property({ tooltip: '答案(用于确定输入框数量和验证)' })
answer: string = '';
}
/**
* 关卡页面组件
* 继承 BaseView实现页面生命周期
@@ -78,9 +57,6 @@ export class PageLevel extends BaseView {
liveLabel: Label | null = null;
// ========== 配置属性 ==========
@property([LevelConfig])
levelConfigs: LevelConfig[] = [];
@property({
min: 0,
tooltip: '当前关卡索引'
@@ -106,9 +82,12 @@ export class PageLevel extends BaseView {
/** 倒计时是否结束 */
private _isTimeUp: boolean = false;
/** 当前关卡配置API 或本地) */
/** 当前关卡配置 */
private _currentConfig: RuntimeLevelConfig | null = null;
/** 是否正在切换关卡(防止重复提交) */
private _isTransitioning: boolean = false;
/**
* 页面首次加载时调用
*/
@@ -147,64 +126,28 @@ export class PageLevel extends BaseView {
}
/**
* 初始化关卡
* 初始化关卡(从 API 数据加载)
*/
private initLevel(): void {
// 优先使用 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] 没有找到 API 关卡配置');
// 降级到本地配置
this._initFromLocalConfig();
console.warn(`[PageLevel] 没有找到关卡配置,索引: ${this.currentLevelIndex}`);
return;
}
console.log(`[PageLevel] 使用 API 配置初始化关卡 ${this.currentLevelIndex + 1}: ${config.name}`);
console.log(`[PageLevel] 初始化关卡 ${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._isTransitioning = false;
// 重置倒计时状态
this._isTimeUp = false;
this._countdown = 60;
@@ -668,6 +611,7 @@ export class PageLevel extends BaseView {
*/
onSubmitAnswer(): void {
if (!this._currentConfig) return;
if (this._isTransitioning) return;
const userAnswer = this.getAnswer();
console.log(`[PageLevel] 提交答案: ${userAnswer}, 正确答案: ${this._currentConfig.answer}`);
@@ -688,6 +632,9 @@ export class PageLevel extends BaseView {
private showSuccess(): void {
console.log('[PageLevel] 答案正确!');
// 标记正在切换关卡,防止重复提交
this._isTransitioning = true;
// 停止倒计时
this.stopCountdown();
@@ -723,10 +670,7 @@ export class PageLevel extends BaseView {
this.currentLevelIndex++;
// 检查是否还有关卡
const manager = LevelDataManager.instance;
const totalLevels = manager.hasApiData()
? manager.getLevelCount()
: this.levelConfigs.length;
const totalLevels = LevelDataManager.instance.getLevelCount();
if (this.currentLevelIndex >= totalLevels) {
// 所有关卡完成

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "b6801da6-5ffd-48d2-8d5c-a2d837c825d3",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -4,32 +4,37 @@ import { SpriteFrame } from 'cc';
* API 返回的单个关卡数据结构
*/
export interface ApiLevelData {
/** 关卡 ID */
id: number;
/** 关卡名称 */
name: string;
/** 关卡 ID (UUID) */
id: string;
/** 关卡序号 */
level: number;
/** 主图 URL */
imageUrl: string;
/** 线索1(映射到 clue1 */
/** 线索1 */
hint1: string;
/** 线索2(映射到 clue2 */
/** 线索2 */
hint2: string;
/** 线索3(映射到 clue3 */
/** 线索3 */
hint3: string;
/** 答案 */
answer: string;
/** 排序 */
sortOrder: number;
}
/**
* API 响应结构
*/
export interface ApiResponse {
/** 状态码0 表示成功 */
code: number;
/** 是否成功 */
success: boolean;
/** 响应消息 */
message: string;
/** 关卡数据数组 */
data: ApiLevelData[];
message: string | null;
/** 响应数据 */
data: {
levels: ApiLevelData[];
total: number;
};
}
/**
@@ -37,7 +42,7 @@ export interface ApiResponse {
*/
export interface RuntimeLevelConfig {
/** 关卡 ID */
id: number;
id: string;
/** 关卡名称 */
name: string;
/** 主图 SpriteFrame可能为 null 如果加载失败) */

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "4cf882b6-b17f-470d-a76b-ea0783d5d424",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "5b29e766-746d-4646-98fd-7908fdd9dbe0",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -119,12 +119,12 @@ export class LevelDataManager {
try {
const response = await HttpUtil.get<ApiResponse>(this.API_URL, this.REQUEST_TIMEOUT);
if (response.code !== 0) {
console.warn(`[LevelDataManager] API 返回错误码: ${response.code}, 消息: ${response.message}`);
if (!response.success) {
console.warn(`[LevelDataManager] API 返回失败, 消息: ${response.message}`);
return null;
}
return response.data;
return response.data.levels;
} catch (error) {
console.error('[LevelDataManager] API 请求失败:', error);
return null;
@@ -149,7 +149,7 @@ export class LevelDataManager {
configs.push({
id: data.id,
name: data.name,
name: `${data.level}`,
spriteFrame: spriteFrame,
clue1: data.hint1,
clue2: data.hint2,

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "082391a3-f1eb-476c-b5b3-810c757f536c",
"files": [],
"subMetas": {},
"userData": {}
}