BulletCount.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { Vec3 } from 'cc';
  2. import { BulletCountConfig, SpawnInfo } from '../BulletTypes';
  3. /**
  4. * BulletCount - 计算子弹生成信息(位置、方向、延迟)
  5. * 仅负责基于数量与扩散/连发逻辑生成 spawn 列表,不包含技能加成。
  6. */
  7. export class BulletCount {
  8. /**
  9. * 计算发射队列
  10. */
  11. static calculateSpawns(countCfg: BulletCountConfig, firePos: Vec3, direction: Vec3): SpawnInfo[] {
  12. const dir = direction?.clone() ?? new Vec3(1, 0, 0);
  13. if (dir.length() === 0) dir.set(1, 0, 0);
  14. dir.normalize();
  15. const result: SpawnInfo[] = [];
  16. const type = countCfg?.type ?? 'single';
  17. const amount = Math.max(1, countCfg?.amount ?? 1);
  18. const spreadAngle = countCfg?.spreadAngle ?? 0;
  19. const burstCount = Math.max(1, countCfg?.burstCount ?? 1);
  20. const burstDelay = Math.max(0, countCfg?.burstDelay ?? 0); // 秒
  21. if (type === 'single') {
  22. for (let i = 0; i < amount; i++) {
  23. result.push({ position: firePos.clone(), direction: dir.clone(), delayMs: 0 });
  24. }
  25. return result;
  26. }
  27. if (type === 'spread') {
  28. // 在 [-spread/2, +spread/2] 范围内平均分布
  29. const count = amount;
  30. const step = count > 1 ? spreadAngle / (count - 1) : 0;
  31. const start = -spreadAngle / 2;
  32. for (let i = 0; i < count; i++) {
  33. const deg = start + step * i;
  34. const rad = (deg * Math.PI) / 180;
  35. const d = rotateVec(dir, rad);
  36. result.push({ position: firePos.clone(), direction: d, delayMs: 0 });
  37. }
  38. return result;
  39. }
  40. if (type === 'burst') {
  41. // 连发:每次 burst 发 amount 发子弹,总计 burstCount 次;每次之间间隔 burstDelay
  42. const ms = Math.floor(burstDelay * 1000);
  43. for (let b = 0; b < burstCount; b++) {
  44. const delayMs = ms * b;
  45. for (let i = 0; i < amount; i++) {
  46. result.push({ position: firePos.clone(), direction: dir.clone(), delayMs });
  47. }
  48. }
  49. return result;
  50. }
  51. // 默认回退到单发
  52. result.push({ position: firePos.clone(), direction: dir.clone(), delayMs: 0 });
  53. return result;
  54. }
  55. }
  56. function rotateVec(v: Vec3, rad: number): Vec3 {
  57. const c = Math.cos(rad);
  58. const s = Math.sin(rad);
  59. return new Vec3(v.x * c - v.y * s, v.x * s + v.y * c, v.z);
  60. }