feat: 支持关卡数据
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -7,27 +7,6 @@ import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
|
|||||||
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
|
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
|
||||||
const { ccclass, property } = _decorator;
|
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,实现页面生命周期
|
* 继承 BaseView,实现页面生命周期
|
||||||
@@ -78,9 +57,6 @@ export class PageLevel extends BaseView {
|
|||||||
liveLabel: Label | null = null;
|
liveLabel: Label | null = null;
|
||||||
|
|
||||||
// ========== 配置属性 ==========
|
// ========== 配置属性 ==========
|
||||||
@property([LevelConfig])
|
|
||||||
levelConfigs: LevelConfig[] = [];
|
|
||||||
|
|
||||||
@property({
|
@property({
|
||||||
min: 0,
|
min: 0,
|
||||||
tooltip: '当前关卡索引'
|
tooltip: '当前关卡索引'
|
||||||
@@ -106,9 +82,12 @@ export class PageLevel extends BaseView {
|
|||||||
/** 倒计时是否结束 */
|
/** 倒计时是否结束 */
|
||||||
private _isTimeUp: boolean = false;
|
private _isTimeUp: boolean = false;
|
||||||
|
|
||||||
/** 当前关卡配置(API 或本地) */
|
/** 当前关卡配置 */
|
||||||
private _currentConfig: RuntimeLevelConfig | null = null;
|
private _currentConfig: RuntimeLevelConfig | null = null;
|
||||||
|
|
||||||
|
/** 是否正在切换关卡(防止重复提交) */
|
||||||
|
private _isTransitioning: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面首次加载时调用
|
* 页面首次加载时调用
|
||||||
*/
|
*/
|
||||||
@@ -147,64 +126,28 @@ export class PageLevel extends BaseView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化关卡
|
* 初始化关卡(从 API 数据加载)
|
||||||
*/
|
*/
|
||||||
private initLevel(): void {
|
private initLevel(): void {
|
||||||
// 优先使用 API 数据
|
|
||||||
if (LevelDataManager.instance.hasApiData()) {
|
|
||||||
this._initFromApiConfig();
|
|
||||||
} else {
|
|
||||||
this._initFromLocalConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从 API 配置初始化关卡
|
|
||||||
*/
|
|
||||||
private _initFromApiConfig(): void {
|
|
||||||
const config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
|
const config = LevelDataManager.instance.getLevelConfig(this.currentLevelIndex);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
console.warn('[PageLevel] 没有找到 API 关卡配置');
|
console.warn(`[PageLevel] 没有找到关卡配置,索引: ${this.currentLevelIndex}`);
|
||||||
// 降级到本地配置
|
|
||||||
this._initFromLocalConfig();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[PageLevel] 使用 API 配置初始化关卡 ${this.currentLevelIndex + 1}: ${config.name}`);
|
console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}: ${config.name}`);
|
||||||
this._applyLevelConfig(config);
|
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 {
|
private _applyLevelConfig(config: RuntimeLevelConfig): void {
|
||||||
this._currentConfig = config;
|
this._currentConfig = config;
|
||||||
|
|
||||||
|
// 重置关卡切换状态,允许再次提交
|
||||||
|
this._isTransitioning = false;
|
||||||
|
|
||||||
// 重置倒计时状态
|
// 重置倒计时状态
|
||||||
this._isTimeUp = false;
|
this._isTimeUp = false;
|
||||||
this._countdown = 60;
|
this._countdown = 60;
|
||||||
@@ -668,6 +611,7 @@ export class PageLevel extends BaseView {
|
|||||||
*/
|
*/
|
||||||
onSubmitAnswer(): void {
|
onSubmitAnswer(): void {
|
||||||
if (!this._currentConfig) return;
|
if (!this._currentConfig) return;
|
||||||
|
if (this._isTransitioning) return;
|
||||||
|
|
||||||
const userAnswer = this.getAnswer();
|
const userAnswer = this.getAnswer();
|
||||||
console.log(`[PageLevel] 提交答案: ${userAnswer}, 正确答案: ${this._currentConfig.answer}`);
|
console.log(`[PageLevel] 提交答案: ${userAnswer}, 正确答案: ${this._currentConfig.answer}`);
|
||||||
@@ -688,6 +632,9 @@ export class PageLevel extends BaseView {
|
|||||||
private showSuccess(): void {
|
private showSuccess(): void {
|
||||||
console.log('[PageLevel] 答案正确!');
|
console.log('[PageLevel] 答案正确!');
|
||||||
|
|
||||||
|
// 标记正在切换关卡,防止重复提交
|
||||||
|
this._isTransitioning = true;
|
||||||
|
|
||||||
// 停止倒计时
|
// 停止倒计时
|
||||||
this.stopCountdown();
|
this.stopCountdown();
|
||||||
|
|
||||||
@@ -723,10 +670,7 @@ export class PageLevel extends BaseView {
|
|||||||
this.currentLevelIndex++;
|
this.currentLevelIndex++;
|
||||||
|
|
||||||
// 检查是否还有关卡
|
// 检查是否还有关卡
|
||||||
const manager = LevelDataManager.instance;
|
const totalLevels = LevelDataManager.instance.getLevelCount();
|
||||||
const totalLevels = manager.hasApiData()
|
|
||||||
? manager.getLevelCount()
|
|
||||||
: this.levelConfigs.length;
|
|
||||||
|
|
||||||
if (this.currentLevelIndex >= totalLevels) {
|
if (this.currentLevelIndex >= totalLevels) {
|
||||||
// 所有关卡完成
|
// 所有关卡完成
|
||||||
|
|||||||
9
assets/scripts/types.meta
Normal file
9
assets/scripts/types.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.2.0",
|
||||||
|
"importer": "directory",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "b6801da6-5ffd-48d2-8d5c-a2d837c825d3",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -4,32 +4,37 @@ import { SpriteFrame } from 'cc';
|
|||||||
* API 返回的单个关卡数据结构
|
* API 返回的单个关卡数据结构
|
||||||
*/
|
*/
|
||||||
export interface ApiLevelData {
|
export interface ApiLevelData {
|
||||||
/** 关卡 ID */
|
/** 关卡 ID (UUID) */
|
||||||
id: number;
|
id: string;
|
||||||
/** 关卡名称 */
|
/** 关卡序号 */
|
||||||
name: string;
|
level: number;
|
||||||
/** 主图 URL */
|
/** 主图 URL */
|
||||||
imageUrl: string;
|
imageUrl: string;
|
||||||
/** 线索1(映射到 clue1) */
|
/** 线索1 */
|
||||||
hint1: string;
|
hint1: string;
|
||||||
/** 线索2(映射到 clue2) */
|
/** 线索2 */
|
||||||
hint2: string;
|
hint2: string;
|
||||||
/** 线索3(映射到 clue3) */
|
/** 线索3 */
|
||||||
hint3: string;
|
hint3: string;
|
||||||
/** 答案 */
|
/** 答案 */
|
||||||
answer: string;
|
answer: string;
|
||||||
|
/** 排序 */
|
||||||
|
sortOrder: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 响应结构
|
* API 响应结构
|
||||||
*/
|
*/
|
||||||
export interface ApiResponse {
|
export interface ApiResponse {
|
||||||
/** 状态码,0 表示成功 */
|
/** 是否成功 */
|
||||||
code: number;
|
success: boolean;
|
||||||
/** 响应消息 */
|
/** 响应消息 */
|
||||||
message: string;
|
message: string | null;
|
||||||
/** 关卡数据数组 */
|
/** 响应数据 */
|
||||||
data: ApiLevelData[];
|
data: {
|
||||||
|
levels: ApiLevelData[];
|
||||||
|
total: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +42,7 @@ export interface ApiResponse {
|
|||||||
*/
|
*/
|
||||||
export interface RuntimeLevelConfig {
|
export interface RuntimeLevelConfig {
|
||||||
/** 关卡 ID */
|
/** 关卡 ID */
|
||||||
id: number;
|
id: string;
|
||||||
/** 关卡名称 */
|
/** 关卡名称 */
|
||||||
name: string;
|
name: string;
|
||||||
/** 主图 SpriteFrame(可能为 null 如果加载失败) */
|
/** 主图 SpriteFrame(可能为 null 如果加载失败) */
|
||||||
|
|||||||
9
assets/scripts/types/LevelTypes.ts.meta
Normal file
9
assets/scripts/types/LevelTypes.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "4cf882b6-b17f-470d-a76b-ea0783d5d424",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
9
assets/scripts/utils/HttpUtil.ts.meta
Normal file
9
assets/scripts/utils/HttpUtil.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "5b29e766-746d-4646-98fd-7908fdd9dbe0",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -119,12 +119,12 @@ export class LevelDataManager {
|
|||||||
try {
|
try {
|
||||||
const response = await HttpUtil.get<ApiResponse>(this.API_URL, this.REQUEST_TIMEOUT);
|
const response = await HttpUtil.get<ApiResponse>(this.API_URL, this.REQUEST_TIMEOUT);
|
||||||
|
|
||||||
if (response.code !== 0) {
|
if (!response.success) {
|
||||||
console.warn(`[LevelDataManager] API 返回错误码: ${response.code}, 消息: ${response.message}`);
|
console.warn(`[LevelDataManager] API 返回失败, 消息: ${response.message}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.data;
|
return response.data.levels;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[LevelDataManager] API 请求失败:', error);
|
console.error('[LevelDataManager] API 请求失败:', error);
|
||||||
return null;
|
return null;
|
||||||
@@ -149,7 +149,7 @@ export class LevelDataManager {
|
|||||||
|
|
||||||
configs.push({
|
configs.push({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
name: data.name,
|
name: `第${data.level}关`,
|
||||||
spriteFrame: spriteFrame,
|
spriteFrame: spriteFrame,
|
||||||
clue1: data.hint1,
|
clue1: data.hint1,
|
||||||
clue2: data.hint2,
|
clue2: data.hint2,
|
||||||
|
|||||||
9
assets/scripts/utils/LevelDataManager.ts.meta
Normal file
9
assets/scripts/utils/LevelDataManager.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "082391a3-f1eb-476c-b5b3-810c757f536c",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user