import { _decorator, Component, Node, Vec3, instantiate } from 'cc'; import { SkillManager } from '../SkillSelection/SkillManager'; // 导入SkillManager(用于多重射击技能) import { WeaponBullet } from '../WeaponBullet'; // 正确导入WeaponBullet import { BulletCountConfig } from '../../Core/ConfigManager'; const { ccclass, property } = _decorator; /** * 子弹数量控制器 * 负责根据配置生成不同数量和模式的子弹 */ export interface BulletSpawnInfo { position: Vec3; // 发射位置 direction: Vec3; // 发射方向 delay: number; // 延迟时间 index: number; // 子弹索引 } @ccclass('BulletCount') export class BulletCount extends Component { /** * 根据配置计算所有子弹的生成信息 * @param config 子弹数量配置 * @param firePosition 发射位置 * @param baseDirection 基础方向 * @returns 子弹生成信息数组 */ public static calculateBulletSpawns( config: BulletCountConfig, firePosition: Vec3, baseDirection: Vec3 ): BulletSpawnInfo[] { const spawns: BulletSpawnInfo[] = []; switch (config.type) { case 'single': spawns.push(...this.createSingleShot(config, firePosition, baseDirection)); break; case 'spread': spawns.push(...this.createSpreadShot(config, firePosition, baseDirection)); break; case 'burst': spawns.push(...this.createBurstShot(config, firePosition, baseDirection)); break; } return spawns; } /** * 单发模式 */ private static createSingleShot( config: BulletCountConfig, firePosition: Vec3, baseDirection: Vec3 ): BulletSpawnInfo[] { return [{ position: firePosition.clone(), direction: baseDirection.clone().normalize(), delay: 0, index: 0 }]; } /** * 散射模式 - 同时发射多颗子弹,呈扇形分布 */ private static createSpreadShot( config: BulletCountConfig, firePosition: Vec3, baseDirection: Vec3 ): BulletSpawnInfo[] { const spawns: BulletSpawnInfo[] = []; const bulletCount = config.amount; const spreadAngleRad = config.spreadAngle * Math.PI / 180; if (bulletCount === 1) { // 只有一颗子弹时,直接使用基础方向 return this.createSingleShot(config, firePosition, baseDirection); } // 计算每颗子弹的角度偏移 const angleStep = spreadAngleRad / (bulletCount - 1); const startAngle = -spreadAngleRad / 2; for (let i = 0; i < bulletCount; i++) { const angle = startAngle + angleStep * i; const direction = this.rotateVector(baseDirection, angle); spawns.push({ position: firePosition.clone(), direction: direction.normalize(), delay: 0, index: i }); } return spawns; } /** * 连发模式 - 按时间间隔依次发射子弹 */ private static createBurstShot( config: BulletCountConfig, firePosition: Vec3, baseDirection: Vec3 ): BulletSpawnInfo[] { const spawns: BulletSpawnInfo[] = []; const burstCount = config.burstCount || config.amount; for (let i = 0; i < burstCount; i++) { spawns.push({ position: firePosition.clone(), direction: baseDirection.clone().normalize(), delay: i * config.burstDelay, index: i }); } return spawns; } /** * 旋转向量 */ private static rotateVector(vector: Vec3, angleRad: number): Vec3 { const cos = Math.cos(angleRad); const sin = Math.sin(angleRad); return new Vec3( vector.x * cos - vector.y * sin, vector.x * sin + vector.y * cos, vector.z ); } /** * 创建散射位置偏移(可选功能,用于霰弹枪等) */ public static createSpreadPositions( basePosition: Vec3, spreadRadius: number, count: number ): Vec3[] { const positions: Vec3[] = []; if (count === 1) { positions.push(basePosition.clone()); return positions; } const angleStep = (Math.PI * 2) / count; for (let i = 0; i < count; i++) { const angle = angleStep * i; const offset = new Vec3( Math.cos(angle) * spreadRadius, Math.sin(angle) * spreadRadius, 0 ); positions.push(basePosition.clone().add(offset)); } return positions; } /** * 验证配置有效性 */ public static validateConfig(config: BulletCountConfig): boolean { if (!config) return false; // 检查基本参数 if (config.amount <= 0) return false; if (config.spreadAngle < 0 || config.spreadAngle > 360) return false; if (config.burstDelay < 0) return false; // 检查类型特定参数 switch (config.type) { case 'spread': if (config.amount > 20) { console.warn('散射子弹数量过多,可能影响性能'); return false; } break; case 'burst': if (config.burstCount <= 0) return false; if (config.burstDelay <= 0.01) { console.warn('连发间隔过短,可能影响性能'); } break; } return true; } /** * 创建多发子弹 */ public static createBullets(initData: any, bulletPrefab: Node): Node[] { // 关卡备战或其他情况下可关闭生成 if (!(window as any).WeaponBullet?.shootingEnabled) return []; // 检查游戏是否暂停,暂停时不创建子弹 const gamePause = (window as any).GamePause?.getInstance?.(); if (gamePause && !gamePause.isBulletFireEnabled()) { return []; } // 获取武器配置 const config = initData.weaponConfig || (window as any).WeaponBullet?.getWeaponConfig?.(initData.weaponId); if (!config) { return []; } // === 应用多重射击技能 === const modifiedConfig = BulletCount.applyMultiShotSkill(config); // === 计算基础发射方向 === let direction: Vec3; if (initData.direction) { direction = initData.direction.clone(); } else if (initData.autoTarget) { // 使用 EnemyController 单例获取最近敌人,避免频繁 find const enemyController = (window as any).EnemyController?.getInstance?.(); if (enemyController) { const nearestEnemy = enemyController.getNearestEnemy(initData.firePosition); if (nearestEnemy) { direction = nearestEnemy.worldPosition.clone().subtract(initData.firePosition).normalize(); } } // 如果没有敌人或计算失败,则回退为随机方向 if (!direction) { const angleRand = Math.random() * Math.PI * 2; direction = new Vec3(Math.cos(angleRand), Math.sin(angleRand), 0); } } else { direction = new Vec3(1, 0, 0); } const spawnInfos = BulletCount.calculateBulletSpawns( modifiedConfig.bulletConfig.count, initData.firePosition, direction ); const bullets: Node[] = []; // 为每个子弹创建实例 for (const spawnInfo of spawnInfos) { const createBullet = () => { const bullet = instantiate(bulletPrefab); const weaponBullet = bullet.getComponent(WeaponBullet) || bullet.addComponent(WeaponBullet); // 初始化子弹 weaponBullet.init({ ...initData, firePosition: spawnInfo.position, direction: spawnInfo.direction, weaponConfig: modifiedConfig }); bullets.push(bullet); }; // 处理延迟发射 if (spawnInfo.delay > 0) { setTimeout(createBullet, spawnInfo.delay * 1000); } else { createBullet(); } } return bullets; } /** * 应用多重射击技能效果 * @param originalConfig 原始武器配置 * @returns 应用技能后的武器配置 */ public static applyMultiShotSkill(originalConfig: any): any { // 获取SkillManager实例 const skillManager = SkillManager.getInstance(); if (!skillManager) { return originalConfig; // 如果没有技能管理器,返回原配置 } // 获取多重射击技能等级 const multiShotSkillLevel = skillManager.getSkillLevel('multi_shots'); console.log("技能等级",multiShotSkillLevel); if (multiShotSkillLevel <= 0) { return originalConfig; // 技能等级为0,返回原配置 } // // 检查是否为单发武器(amount = 1 且 type = 'single') const bulletCountConfig = originalConfig.bulletConfig.count; // const isSingleShotWeapon = bulletCountConfig.type === 'single' && bulletCountConfig.amount === 1; // if (!isSingleShotWeapon) { // return originalConfig; // 多发武器不受影响,返回原配置 // } // 计算多重射击几率 const baseMultiShotChance = 0; // 基础几率为0 const multiShotChance = SkillManager.calculateMultiShotChance(baseMultiShotChance, multiShotSkillLevel); // 检查是否触发多重射击 const shouldTriggerMultiShot = SkillManager.rollMultiShot(multiShotChance); if (!shouldTriggerMultiShot) { return originalConfig; // 未触发多重射击,返回原配置 } // 触发多重射击,计算子弹数量 const baseBulletCount = 1; const multiShotBulletCount = SkillManager.calculateMultiShotBulletCount(baseBulletCount, multiShotSkillLevel); // 创建修改后的配置 const modifiedConfig: any = JSON.parse(JSON.stringify(originalConfig)); // 深拷贝 // 修改子弹配置为散射模式 modifiedConfig.bulletConfig.count = { type: 'spread', amount: multiShotBulletCount, spreadAngle: 30, // 30度散射角度,可以根据需要调整 burstCount: bulletCountConfig.burstCount || 1, burstDelay: bulletCountConfig.burstDelay || 0 }; console.log(`多重射击触发!技能等级: ${multiShotSkillLevel}, 子弹数量: ${multiShotBulletCount}`); return modifiedConfig; } }