import { Vec3 } from 'cc'; import { BulletCountConfig, SpawnInfo } from '../BulletTypes'; /** * BulletCount - 计算子弹生成信息(位置、方向、延迟) * 仅负责基于数量与扩散/连发逻辑生成 spawn 列表,不包含技能加成。 */ export class BulletCount { /** * 计算发射队列 */ static calculateSpawns(countCfg: BulletCountConfig, firePos: Vec3, direction: Vec3): SpawnInfo[] { const dir = direction?.clone() ?? new Vec3(1, 0, 0); if (dir.length() === 0) dir.set(1, 0, 0); dir.normalize(); const result: SpawnInfo[] = []; const type = countCfg?.type ?? 'single'; const amount = Math.max(1, countCfg?.amount ?? 1); const spreadAngle = countCfg?.spreadAngle ?? 0; const burstCount = Math.max(1, countCfg?.burstCount ?? 1); const burstDelay = Math.max(0, countCfg?.burstDelay ?? 0); // 秒 if (type === 'single') { for (let i = 0; i < amount; i++) { result.push({ position: firePos.clone(), direction: dir.clone(), delayMs: 0 }); } return result; } if (type === 'spread') { // 在 [-spread/2, +spread/2] 范围内平均分布 const count = amount; const step = count > 1 ? spreadAngle / (count - 1) : 0; const start = -spreadAngle / 2; for (let i = 0; i < count; i++) { const deg = start + step * i; const rad = (deg * Math.PI) / 180; const d = rotateVec(dir, rad); result.push({ position: firePos.clone(), direction: d, delayMs: 0 }); } return result; } if (type === 'burst') { // 连发:每次 burst 发 amount 发子弹,总计 burstCount 次;每次之间间隔 burstDelay const ms = Math.floor(burstDelay * 1000); for (let b = 0; b < burstCount; b++) { const delayMs = ms * b; for (let i = 0; i < amount; i++) { result.push({ position: firePos.clone(), direction: dir.clone(), delayMs }); } } return result; } // 默认回退到单发 result.push({ position: firePos.clone(), direction: dir.clone(), delayMs: 0 }); return result; } } function rotateVec(v: Vec3, rad: number): Vec3 { const c = Math.cos(rad); const s = Math.sin(rad); return new Vec3(v.x * c - v.y * s, v.x * s + v.y * c, v.z); }