import { _decorator, Component, JsonAsset, resources } from 'cc'; const { ccclass, property } = _decorator; /** * 关卡配置数据结构 */ interface LevelConfig { levelId: number; name: string; scene: string; description?: string; backgroundImage?: string; // 背景图片路径 weapons: string[]; waves: WaveConfig[]; levelSettings?: { initialHealth?: number; timeLimit?: number; difficulty?: string; energyMax?: number; healthMultiplier?: number; }; } /** * 波次配置数据结构 */ interface WaveConfig { waveId: number; enemies: EnemyWaveConfig[]; } /** * 敌人波次配置 */ interface EnemyWaveConfig { enemyType: string; count: number; spawnInterval: number; characteristics: string[]; } /** * 关卡JSON文件配置项 */ @ccclass('LevelJsonConfig') export class LevelJsonConfig { @property({ tooltip: '关卡ID' }) public levelId: number = 1; @property({ tooltip: '关卡名称' }) public levelName: string = ''; @property({ type: JsonAsset, tooltip: '关卡配置JSON文件' }) public configFile: JsonAsset = null; } /** * 关卡配置管理器 * 让策划在编辑器中配置所有关卡的JSON文件 */ @ccclass('LevelConfigManager') export class LevelConfigManager extends Component { private static instance: LevelConfigManager = null; @property({ tooltip: '总关卡数量' }) public totalLevels: number = 5; @property({ type: [LevelJsonConfig], tooltip: '关卡配置列表(拖入对应的JSON文件)' }) public levelConfigs: LevelJsonConfig[] = []; // 缓存已加载的关卡配置 private loadedConfigs: Map = new Map(); onLoad() { if (LevelConfigManager.instance === null) { LevelConfigManager.instance = this; this.validateConfigs(); } else if (LevelConfigManager.instance !== this) { this.destroy(); return; } } onDestroy() { if (LevelConfigManager.instance === this) { LevelConfigManager.instance = null; } } public static getInstance(): LevelConfigManager { return LevelConfigManager.instance; } /** * 验证关卡配置的完整性 */ private validateConfigs() { // 检查是否所有关卡都有配置 for (let i = 1; i <= this.totalLevels; i++) { const config = this.levelConfigs.find(c => c.levelId === i); if (!config) { console.warn(`关卡 ${i} 缺少配置`); } else if (!config.configFile) { console.warn(`关卡 ${i} 缺少JSON文件`); } } // 检查是否有重复的关卡ID const levelIds = this.levelConfigs.map(c => c.levelId); const duplicates = levelIds.filter((id, index) => levelIds.indexOf(id) !== index); if (duplicates.length > 0) { console.error(`发现重复的关卡ID: ${duplicates.join(', ')}`); } } /** * 获取关卡配置 */ public async getLevelConfig(levelId: number): Promise { // 先从缓存中查找 if (this.loadedConfigs.has(levelId)) { return this.loadedConfigs.get(levelId); } // 查找对应的配置项 const configItem = this.levelConfigs.find(c => c.levelId === levelId); if (!configItem || !configItem.configFile) { console.error(`关卡 ${levelId} 配置不存在或缺少JSON文件`); return null; } try { // 解析JSON数据 const jsonData = configItem.configFile.json; if (!jsonData) { console.error(`关卡 ${levelId} JSON文件解析失败`); return null; } // 验证JSON数据结构 const levelConfig = this.validateLevelConfigData(jsonData, levelId); if (levelConfig) { // 缓存配置 this.loadedConfigs.set(levelId, levelConfig); return levelConfig; } } catch (error) { console.error(`关卡 ${levelId} 配置加载失败:`, error); } return null; } /** * 验证关卡配置数据结构 */ private validateLevelConfigData(jsonData: any, levelId: number): LevelConfig | null { try { // 基本字段验证 const weapons = jsonData.weapons || jsonData.availableWeapons; if (!jsonData.name || !jsonData.scene || !weapons) { console.error(`关卡 ${levelId} JSON数据缺少必要字段`); if (!jsonData.name) console.error(` 缺少字段: name`); if (!jsonData.scene) console.error(` 缺少字段: scene`); if (!weapons) console.error(` 缺少字段: weapons 或 availableWeapons`); return null; } // 检查武器列表是否为空 if (!Array.isArray(weapons) || weapons.length === 0) { console.error(`关卡 ${levelId} 没有配置武器列表`); return null; } // 构建关卡配置对象 const levelConfig: LevelConfig = { levelId: levelId, name: jsonData.name, scene: jsonData.scene, description: jsonData.description, backgroundImage: jsonData.backgroundImage, // 添加背景图片字段 weapons: weapons, waves: [], levelSettings: { timeLimit: jsonData.timeLimit, difficulty: jsonData.difficulty, healthMultiplier: jsonData.healthMultiplier, ...jsonData.levelSettings } }; // 验证波次配置 if (Array.isArray(jsonData.waves)) { for (const waveData of jsonData.waves) { const wave: WaveConfig = { waveId: waveData.waveId || 0, enemies: [] }; if (Array.isArray(waveData.enemies)) { for (const enemyData of waveData.enemies) { const enemy: EnemyWaveConfig = { enemyType: enemyData.enemyType || '', count: enemyData.count || 1, spawnInterval: enemyData.spawnInterval || 5, characteristics: enemyData.characteristics || [] }; wave.enemies.push(enemy); } } levelConfig.waves.push(wave); } } return levelConfig; } catch (error) { console.error(`关卡 ${levelId} 数据验证失败:`, error); return null; } } /** * 获取所有可用关卡ID列表 */ public getAvailableLevels(): number[] { return this.levelConfigs .filter(config => config.configFile !== null) .map(config => config.levelId) .sort((a, b) => a - b); } /** * 获取关卡名称 */ public getLevelName(levelId: number): string { const config = this.levelConfigs.find(c => c.levelId === levelId); return config ? config.levelName : `关卡 ${levelId}`; } /** * 检查关卡是否已配置 */ public isLevelConfigured(levelId: number): boolean { const config = this.levelConfigs.find(c => c.levelId === levelId); return config !== undefined && config.configFile !== null; } /** * 获取总关卡数 */ public getTotalLevels(): number { return this.totalLevels; } /** * 重新加载所有关卡配置(开发调试用) */ public reloadAllConfigs() { this.loadedConfigs.clear(); this.validateConfigs(); } /** * 创建示例关卡配置(开发辅助) */ public generateSampleConfig(levelId: number): LevelConfig { const samples = { 1: { name: '新手引导(草地平原)', scene: 'grassland', backgroundImage: 'images/LevelBackground/BG1', weapons: ['毛豆射手', '尖胡萝卜'], waves: [ { waveId: 1, enemies: [ { enemyType: '普通僵尸', count: 8, spawnInterval: 5, characteristics: ['中速移动', '无技能'] } ] }, { waveId: 2, enemies: [ { enemyType: '普通僵尸', count: 10, spawnInterval: 5, characteristics: ['中速移动', '无技能'] } ] }, { waveId: 3, enemies: [ { enemyType: '路障僵尸', count: 5, spawnInterval: 6, characteristics: ['高生命', '慢速移动'] } ] } ] }, 2: { name: '丛林探险(森林场景)', scene: 'forest', backgroundImage: 'images/LevelBackground/BG2', weapons: ['锯齿草', '西瓜炸弹', '毛豆射手'], waves: [ { waveId: 1, enemies: [ { enemyType: '普通僵尸', count: 10, spawnInterval: 4, characteristics: ['中速移动', '无技能'] } ] }, { waveId: 2, enemies: [ { enemyType: '漫步僵尸', count: 6, spawnInterval: 5, characteristics: ['左右摇摆', '近战范围大'] } ] } ] } }; return samples[levelId] || samples[1]; } /** * 调试:打印所有关卡配置信息 */ public debugPrintAllConfigs() { console.log(`=== 所有关卡配置信息 ===`); console.log(`总关卡数: ${this.totalLevels}`); for (const config of this.levelConfigs) { console.log(`关卡 ${config.levelId}: ${config.levelName}`); console.log(` JSON文件: ${config.configFile ? config.configFile.name : '未设置'}`); } } }