| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- 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[];
- healthMultiplier?: number;
- }
- /**
- * 敌人波次配置
- */
- interface EnemyWaveConfig {
- enemyType: string;
- count: number;
- spawnInterval: number;
- characteristics: string[];
- }
- /**
- * 关卡配置管理器
- * 让策划在编辑器中配置所有关卡的JSON文件
- */
- @ccclass('LevelConfigManager')
- export class LevelConfigManager extends Component {
- private static instance: LevelConfigManager = null;
- @property({
- tooltip: '总关卡数量'
- })
- public totalLevels: number = 5;
- @property({
- type: [JsonAsset],
- tooltip: '关卡配置文件列表(按关卡序号排列)'
- })
- public levelConfigs: JsonAsset[] = [];
- // 缓存已加载的关卡配置
- private loadedConfigs: Map<number, LevelConfig> = 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() {
- // 检查是否所有关卡都有配置(按数组索引对应关卡ID)
- for (let i = 1; i <= this.totalLevels; i++) {
- const configFile = this.levelConfigs[i - 1];
- if (!configFile) {
- console.warn(`关卡 ${i} 缺少JSON文件`);
- }
- }
- }
- /**
- * 获取关卡配置
- */
- public async getLevelConfig(levelId: number): Promise<LevelConfig | null> {
- // 先从缓存中查找
- if (this.loadedConfigs.has(levelId)) {
- return this.loadedConfigs.get(levelId);
- }
- // 按数组索引查找对应的配置文件
- const configFile = this.levelConfigs[levelId - 1];
- if (!configFile) {
- console.error(`关卡 ${levelId} 配置不存在或缺少JSON文件`);
- return null;
- }
- try {
- // 解析JSON数据
- const jsonData = 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: [],
- healthMultiplier: waveData.healthMultiplier
- };
- 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[] {
- const ids: number[] = [];
- for (let i = 0; i < this.levelConfigs.length; i++) {
- if (this.levelConfigs[i]) {
- ids.push(i + 1);
- }
- }
- return ids.sort((a, b) => a - b);
- }
- /**
- * 获取关卡名称
- */
- public getLevelName(levelId: number): string {
- const asset = this.levelConfigs[levelId - 1];
- return asset ? (asset.name || `关卡 ${levelId}`) : `关卡 ${levelId}`;
- }
- /**
- * 检查关卡是否已配置
- */
- public isLevelConfigured(levelId: number): boolean {
- return !!this.levelConfigs[levelId - 1];
- }
- /**
- * 获取总关卡数
- */
- public getTotalLevels(): number {
- return this.totalLevels;
- }
- /**
- * 重新加载所有关卡配置(开发调试用)
- */
- public reloadAllConfigs() {
- this.loadedConfigs.clear();
- this.validateConfigs();
- }
- /**
- * 调试:打印所有关卡配置信息
- */
- public debugPrintAllConfigs() {
- console.log(`=== 所有关卡配置信息 ===`);
- console.log(`总关卡数: ${this.totalLevels}`);
-
- for (let i = 0; i < this.levelConfigs.length; i++) {
- const asset = this.levelConfigs[i];
- console.log(`关卡 ${i + 1}: ${asset ? asset.name : '未设置'}`);
- }
- }
- }
|