import { _decorator, Component, Node, Vec3, instantiate } from 'cc'; const { ccclass, property } = _decorator; /** * 子弹数量控制器 * 负责根据配置生成不同数量和模式的子弹 */ export interface BulletCountConfig { type: 'single' | 'spread' | 'burst'; // 发射模式 amount: number; // 子弹数量 spreadAngle: number; // 散射角度(度) burstCount: number; // 连发数量 burstDelay: number; // 连发间隔(秒) } 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; } }