| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- import { _decorator, resources, JsonAsset } from 'cc';
- import { BaseSingleton } from './BaseSingleton';
- const { ccclass, property } = _decorator;
- // 局内金币花费配置接口
- export interface InGameCostConfig {
- baseCost: number;
- shapeCosts: {
- [shapeId: string]: number;
- };
- }
- // 弹道配置接口
- export interface BulletTrajectoryConfig {
- type: string;
- speed: number;
- gravity: number;
- arcHeight: number;
- homingStrength: number;
- homingDelay: number;
- rotateSpeed?: number; // 旋转速率 (0~1),仅在 arc 弹道中使用
- }
- // 弹药数量配置接口
- export interface BulletCountConfig {
- type: string;
- amount: number;
- spreadAngle: number;
- burstCount: number;
- burstDelay: number;
- }
- // 命中效果配置接口
- export interface HitEffectConfig {
- type: string;
- priority: number;
- damage?: number;
- pierceCount?: number;
- radius?: number;
- delay?: number;
- duration?: number;
- tickInterval?: number;
- ricochetCount?: number;
- ricochetAngle?: number;
- [key: string]: any;
- }
- // 弹药生命周期配置接口
- export interface BulletLifecycleConfig {
- type: string;
- maxLifetime: number;
- penetration: number;
- ricochetCount: number;
- returnToOrigin: boolean;
- returnDelay?: number; // 返回延迟(秒)
- maxRange?: number; // 最大射程
- effectDuration?: number; // 效果持续时间(用于地面效果)
- }
- // 武器配置接口
- export interface WeaponConfig {
- id: string;
- name: string;
- type: string;
- rarity?: string; // 可选字段,支持动态稀有度(合成时可变)
- stats: {
- damage: number;
- fireRate: number;
- range: number;
- bulletSpeed: number;
- accuracy?: number;
- };
- bulletConfig: {
- count: BulletCountConfig;
- trajectory: BulletTrajectoryConfig;
- hitEffects: HitEffectConfig[];
- lifecycle: BulletLifecycleConfig;
- visual: {
- bulletImages: string;
- hitEffect: string;
- trailEffect?: string;
- explosionEffect?: string;
- };
- };
- visualConfig: {
- weaponSprites: {
- [shapeId: string]: string;
- };
- attackSound: string;
- };
- upgradeConfig: {
- maxLevel: number;
- levels: {
- [level: string]: {
- cost: number;
- damage?: number;
- };
- };
- };
- // 运行时计算的实际数值(应用技能加成后)
- runtimeStats?: {
- finalDamage: number;
- finalCritDamage: number;
- critChance: number;
- };
- inGameCostConfig?: InGameCostConfig;
- }
- // 球控制器配置接口
- export interface BallControllerConfig {
- baseSpeed: number;
- maxReflectionRandomness: number;
- antiTrapTimeWindow: number;
- antiTrapHitThreshold: number;
- deflectionAttemptThreshold: number;
- antiTrapDeflectionMultiplier: number;
- FIRE_COOLDOWN: number;
- ballRadius: number;
- gravityScale: number;
- linearDamping: number;
- angularDamping: number;
- colliderGroup: number;
- colliderTag: number;
- friction: number;
- restitution: number;
- safeDistance: number;
- edgeOffset: number;
- sensor: boolean;
- maxAttempts: number;
- }
- // 敌人配置接口
- export interface EnemyConfig {
- id: string;
- name: string;
- type: string;
- rarity: string;
- health: number;
- speed: number;
- attack: number;
- range: number;
- attackSpeed: number;
- defense: number;
- goldReward: number;
- explosionDamage?: number;
- explosionRadius?: number;
- movement: {
- type: string;
- pattern: string;
- speedVariation: number;
- swayAmplitude?: number;
- swayFrequency?: number;
- };
- combat: {
- attackType: string;
- attackDelay: number;
- attackCooldown: number;
- weaponType?: string;
- projectileType?: string;
- projectileSpeed?: number;
- canBlock: boolean;
- blockChance: number;
- };
- visualConfig: {
- spritePath: string;
- animations: {
- [state: string]: string;
- };
- scale: number;
- flipX: boolean;
- weapon?: string;
- armor?: string;
- prop?: string;
- };
- audioConfig: {
- [sound: string]: string;
- };
- specialAbilities: string[];
- stealthConfig?: {
- stealthDuration: number;
- stealthCooldown: number;
- revealOnAttack: boolean;
- visibilityAlpha: number;
- };
- armorConfig?: {
- armorHealth: number;
- armorReduction: number;
- breakThreshold: number;
- };
- explosionConfig?: {
- explosionDelay: number;
- explosionEffect: string;
- damageRadius: number;
- knockbackForce: number;
- };
- bossConfig?: {
- phases: number;
- phaseHealthThreshold: number;
- enrageBonus?: {
- speed: number;
- damage: number;
- attackSpeed: number;
- };
- summonAbility?: {
- minionType: string;
- summonCount: number;
- summonCooldown: number;
- };
- laserAbility?: {
- damage: number;
- range: number;
- chargeTime: number;
- cooldown: number;
- };
- };
- projectileConfig?: {
- bulletImages: string;
- hitEffect: string;
- trailEffect?: string;
- };
- }
- @ccclass('ConfigManager')
- export class ConfigManager extends BaseSingleton {
- // 仅用于类型声明,实例由 BaseSingleton 在运行时动态维护
- public static _instance: ConfigManager;
-
- private weaponsConfig: any = null;
- private enemiesConfig: any = null;
- private configLoaded: boolean = false;
-
-
- /**
- * BaseSingleton 首次实例化回调
- */
- protected init() {
- console.log('[ConfigManager] 开始初始化配置管理器');
- this.loadConfigs();
- }
- // 加载所有配置文件
- private async loadConfigs() {
- console.log('[ConfigManager] 开始加载配置文件');
- this.configLoaded = false;
-
- try {
- // 确保resources bundle已经准备好
- await this.ensureResourcesBundle();
-
- // 加载武器配置
- console.log('[ConfigManager] 开始加载武器配置');
- await this.loadWeaponsConfig();
- console.log('[ConfigManager] 武器配置加载完成');
-
- // 加载敌人配置
- console.log('[ConfigManager] 开始加载敌人配置');
- await this.loadEnemiesConfig();
- console.log('[ConfigManager] 敌人配置加载完成');
-
- // 注意:球控制器配置现在通过BallController组件的装饰器直接加载
- console.log('[ConfigManager] 球控制器配置通过装饰器加载,跳过ConfigManager加载');
-
- this.configLoaded = true;
- console.log('[ConfigManager] ✅ 所有配置文件加载成功,配置管理器初始化完成');
- } catch (error) {
- console.error('[ConfigManager] ❌ 配置文件加载失败:', error);
- this.configLoaded = false;
-
- // 延迟重试加载
- console.log('[ConfigManager] 将在3秒后重试加载配置');
- setTimeout(() => {
- console.log('[ConfigManager] 开始重试加载配置');
- this.loadConfigs();
- }, 3000);
- }
- }
- // 确保resources bundle已经准备好
- private ensureResourcesBundle(): Promise<void> {
- return new Promise((resolve) => {
- console.log('[ConfigManager] 检查resources bundle状态...');
-
- // 增加延迟时间,确保Cocos Creator资源系统完全初始化
- setTimeout(() => {
- console.log('[ConfigManager] resources bundle初始化等待完成');
- resolve();
- }, 2000); // 增加到2秒
- });
- }
- // 加载武器配置
- private loadWeaponsConfig(): Promise<void> {
- return new Promise((resolve, reject) => {
- console.log('[ConfigManager] 开始加载武器配置...');
- resources.load('data/weapons', JsonAsset, (err, asset) => {
- if (err) {
- console.error('[ConfigManager] 武器配置文件加载失败:', err);
- reject(err);
- return;
- }
-
- if (!asset || !asset.json) {
- console.error('[ConfigManager] 武器配置文件内容为空');
- reject(new Error('武器配置文件内容为空'));
- return;
- }
-
- this.weaponsConfig = asset.json as any;
-
- // 验证配置完整性
- console.log('[ConfigManager] 验证武器配置完整性...');
- if (!this.weaponsConfig.weapons || !Array.isArray(this.weaponsConfig.weapons)) {
- console.error('[ConfigManager] 武器配置格式错误:缺少weapons数组');
- reject(new Error('武器配置格式错误'));
- return;
- }
-
- console.log(`[ConfigManager] 武器配置加载成功,共${this.weaponsConfig.weapons.length}个武器`);
-
- // 检查blockSizes配置
- if (this.weaponsConfig.blockSizes && Array.isArray(this.weaponsConfig.blockSizes)) {
- console.log(`[ConfigManager] ✅ blockSizes配置加载成功,共${this.weaponsConfig.blockSizes.length}个形状`);
- this.weaponsConfig.blockSizes.forEach(shape => {
- console.log(`[ConfigManager] - 形状: ${shape.id} (${shape.name})`);
- });
- } else {
- console.warn('[ConfigManager] ⚠️ blockSizes配置缺失或格式错误');
- }
-
- resolve();
- });
- });
- }
- // 加载敌人配置
- private loadEnemiesConfig(): Promise<void> {
- return new Promise((resolve, reject) => {
- console.log('加载敌人配置...');
- resources.load('data/enemies', JsonAsset, (err, asset) => {
- if (err) {
- console.error('敌人配置文件加载失败:', err);
- reject(err);
- return;
- }
-
- if (!asset || !asset.json) {
- console.error('敌人配置文件内容为空');
- reject(new Error('敌人配置文件内容为空'));
- return;
- }
- this.enemiesConfig = asset.json as any;
- console.log('✅ 敌人配置加载成功');
- resolve();
- });
- });
- }
- // 随机获取武器配置
- public getRandomWeapon(rarity?: string): WeaponConfig | null {
- if (!this.weaponsConfig || !this.weaponsConfig.weapons || this.weaponsConfig.weapons.length === 0) {
- console.warn('武器配置未加载或为空');
- return null;
- }
- if (rarity) {
- // 按稀有度筛选
- const filteredWeapons = this.weaponsConfig.weapons.filter(weapon => weapon.rarity === rarity);
- if (filteredWeapons.length === 0) {
- console.warn(`没有找到稀有度为 ${rarity} 的武器`);
- return null;
- }
- const randomIndex = Math.floor(Math.random() * filteredWeapons.length);
- return filteredWeapons[randomIndex];
- }
- // 使用稀有度权重系统进行随机选择
- const rarityWeights = this.weaponsConfig.rarityWeights;
- if (!rarityWeights) {
- console.warn('稀有度权重配置未找到,使用随机选择');
- const randomIndex = Math.floor(Math.random() * this.weaponsConfig.weapons.length);
- return this.weaponsConfig.weapons[randomIndex];
- }
- // 计算总权重
- // 计算总权重(兼容ES5)
- const totalWeight = Object.keys(rarityWeights).reduce((sum: number, key: string) => sum + (rarityWeights[key] as number), 0);
- const randomValue = Math.random() * totalWeight;
-
- // 根据权重选择稀有度
- let currentWeight = 0;
- let selectedRarity = 'common';
-
- // 兼容ES5的写法遍历对象
- for (let rarity in rarityWeights) {
- if (rarityWeights.hasOwnProperty(rarity)) {
- const weight = rarityWeights[rarity];
- currentWeight += weight as number;
- if (randomValue <= currentWeight) {
- selectedRarity = rarity;
- break;
- }
- }
-
- // 从选中的稀有度中随机选择武器
- const weaponsOfRarity = this.weaponsConfig.weapons.filter(weapon => weapon.rarity === selectedRarity);
- if (weaponsOfRarity.length === 0) {
- console.warn(`稀有度 ${selectedRarity} 没有可用武器,使用随机选择`);
- const randomIndex = Math.floor(Math.random() * this.weaponsConfig.weapons.length);
- return this.weaponsConfig.weapons[randomIndex];
- }
-
- const randomIndex = Math.floor(Math.random() * weaponsOfRarity.length);
- const selectedWeapon = weaponsOfRarity[randomIndex];
-
- console.log(`随机选择武器: ${selectedWeapon.name} (${selectedRarity})`);
- return selectedWeapon;
- }
- }
- // 随机获取敌人配置
- public getRandomEnemy(rarity?: string): EnemyConfig | null {
- // 修复:enemies.json是直接的数组结构,不需要.enemies包装
- if (!this.enemiesConfig || !Array.isArray(this.enemiesConfig) || this.enemiesConfig.length === 0) {
- console.warn('敌人配置未加载或为空');
- return null;
- }
- if (rarity) {
- // 按稀有度筛选
- const filteredEnemies = this.enemiesConfig.filter(enemy => enemy.rarity === rarity);
- if (filteredEnemies.length === 0) {
- console.warn(`没有找到稀有度为 ${rarity} 的敌人`);
- return null;
- }
- const randomIndex = Math.floor(Math.random() * filteredEnemies.length);
- return filteredEnemies[randomIndex];
- }
- // 直接从敌人列表中随机选择
- const randomIndex = Math.floor(Math.random() * this.enemiesConfig.length);
- return this.enemiesConfig[randomIndex];
- }
- // 根据ID获取武器配置
- public getWeaponById(id: string): WeaponConfig | null {
- if (!this.weaponsConfig) return null;
- return this.weaponsConfig.weapons.find(weapon => weapon.id === id) || null;
- }
- // 根据ID获取敌人配置
- public getEnemyById(id: string): EnemyConfig | null {
- // 修复:enemies.json是直接的数组结构,不需要.enemies包装
- if (!this.enemiesConfig || !Array.isArray(this.enemiesConfig)) return null;
- return this.enemiesConfig.find(enemy => enemy.id === id) || null;
- }
- /**
- * 获取敌人名称到ID的映射
- */
- public getNameToIdMapping(): { [key: string]: string } | null {
- if (!this.enemiesConfig) return null;
- return this.enemiesConfig.nameToIdMapping || null;
- }
- // 获取所有武器配置
- public getAllWeapons(): WeaponConfig[] {
- return this.weaponsConfig?.weapons || [];
- }
- // 获取所有敌人配置
- public getAllEnemies(): EnemyConfig[] {
- // 修复:enemies.json是直接的数组结构,不需要.enemies包装
- return Array.isArray(this.enemiesConfig) ? this.enemiesConfig : [];
- }
- // 根据稀有度获取武器列表
- public getWeaponsByRarity(rarity: string): WeaponConfig[] {
- if (!this.weaponsConfig) return [];
- return this.weaponsConfig.weapons.filter(weapon => weapon.rarity === rarity);
- }
- // 根据稀有度获取敌人列表
- public getEnemiesByRarity(rarity: string): EnemyConfig[] {
- // 修复:enemies.json是直接的数组结构,不需要.enemies包装
- if (!this.enemiesConfig || !Array.isArray(this.enemiesConfig)) return [];
- return this.enemiesConfig.filter(enemy => enemy.rarity === rarity);
- }
- // 获取方块尺寸列表(已更新为形状ID)
- public getBlockSizes(): string[] {
- if (!this.weaponsConfig || !this.weaponsConfig.blockSizes) {
- return ['I', 'H-I', 'L', 'S', 'D-T'];
- }
- // 从blockSizes配置中提取形状ID
- return this.weaponsConfig.blockSizes.map((shape: any) => shape.id);
- }
-
- // 获取方块形状配置列表
- public getBlockShapes(): any[] {
- if (!this.weaponsConfig) {
- console.warn('[ConfigManager] 武器配置未加载,无法获取方块形状配置');
- console.warn('[ConfigManager] 配置加载状态:', this.configLoaded);
- return [];
- }
-
- if (!this.weaponsConfig.blockSizes) {
- console.warn('[ConfigManager] 方块形状配置(blockSizes)未找到');
- console.warn('[ConfigManager] 可用的配置字段:', Object.keys(this.weaponsConfig));
- return [];
- }
-
- if (!Array.isArray(this.weaponsConfig.blockSizes)) {
- console.error('[ConfigManager] blockSizes不是数组格式:', typeof this.weaponsConfig.blockSizes);
- return [];
- }
-
- console.log(`[ConfigManager] 成功获取${this.weaponsConfig.blockSizes.length}个方块形状配置`);
- return this.weaponsConfig.blockSizes;
- }
- // 获取波次进展配置(已废弃,波次配置现在通过关卡系统管理)
- public getWaveProgression(): any {
- console.warn('[ConfigManager] getWaveProgression已废弃,波次配置现在通过关卡系统管理');
- return {};
- }
- // 根据波次获取合适的敌人(简化版本,直接返回随机敌人)
- public getEnemyForWave(waveNumber: number): EnemyConfig | null {
- // 修复:波次配置现在通过关卡系统管理,这里简化为返回随机敌人
- // 具体的波次敌人配置由EnemyController通过关卡配置处理
- console.log(`[ConfigManager] 为波次 ${waveNumber} 获取随机敌人`);
- return this.getRandomEnemy();
- }
- // 检查配置是否已加载
- public isConfigLoaded(): boolean {
- return this.configLoaded;
- }
- // 获取球控制器配置
- // getBallControllerConfig方法已移除,球控制器配置现在通过装饰器直接在BallController中加载
- }
|