BulletTrajectory.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { _decorator, Component, Node, Vec3 } from 'cc';
  2. import { BulletTrajectoryConfig } from '../BulletTypes';
  3. const { ccclass } = _decorator;
  4. /**
  5. * 弹道控制(可移植版)
  6. * - straight:匀速直线
  7. * - arc:带重力或弧线(简化为重力)
  8. * - guided:简单追踪(需要调用 setTarget 或外部提供方向更新)
  9. */
  10. @ccclass('BCBulletTrajectory')
  11. export class BulletTrajectory extends Component {
  12. private cfg: BulletTrajectoryConfig | null = null;
  13. private velocity: Vec3 = new Vec3(0, 0, 0);
  14. private target: Node | null = null;
  15. private homingTimer = 0;
  16. private origin: Vec3 = new Vec3();
  17. public init(cfg: BulletTrajectoryConfig, direction: Vec3, startPos: Vec3, originNode?: Node | null) {
  18. this.cfg = { ...cfg };
  19. const speed = Math.max(0, this.cfg.speed ?? 0);
  20. const dir = direction?.clone() ?? new Vec3(1, 0, 0);
  21. if (dir.length() === 0) dir.set(1, 0, 0);
  22. dir.normalize();
  23. this.velocity.set(dir.x * speed, dir.y * speed, 0);
  24. this.node.setPosition(startPos);
  25. this.origin.set(startPos);
  26. this.homingTimer = 0;
  27. }
  28. public setTarget(node: Node | null) {
  29. this.target = node;
  30. }
  31. public getCurrentVelocity(): Vec3 {
  32. return this.velocity.clone();
  33. }
  34. update(dt: number) {
  35. if (!this.cfg) return;
  36. const type = this.cfg.type;
  37. if (type === 'straight') {
  38. this.moveLinear(dt);
  39. } else if (type === 'arc') {
  40. this.moveArc(dt);
  41. } else if (type === 'guided') {
  42. this.moveGuided(dt);
  43. } else {
  44. this.moveLinear(dt);
  45. }
  46. }
  47. private moveLinear(dt: number) {
  48. const dx = this.velocity.x * dt;
  49. const dy = this.velocity.y * dt;
  50. const p = this.node.position;
  51. this.node.setPosition(p.x + dx, p.y + dy);
  52. }
  53. private moveArc(dt: number) {
  54. const g = this.cfg?.gravity ?? 0;
  55. // 简化:重力沿 y 轴正方向(向下)
  56. this.velocity.y -= g * dt;
  57. this.moveLinear(dt);
  58. }
  59. private moveGuided(dt: number) {
  60. const delay = Math.max(0, this.cfg?.homingDelay ?? 0);
  61. this.homingTimer += dt;
  62. if (this.homingTimer >= delay && this.target && this.target.isValid) {
  63. const pos = this.node.worldPosition;
  64. const tpos = this.target.worldPosition;
  65. const toTarget = new Vec3(tpos.x - pos.x, tpos.y - pos.y, 0);
  66. const dist = toTarget.length();
  67. if (dist > 1e-3) {
  68. toTarget.normalize();
  69. const strength = Math.max(0, Math.min(1, this.cfg?.homingStrength ?? 0));
  70. // 插值改变速度方向,但保持速率(magnitude)接近 cfg.speed
  71. const speed = Math.max(0, this.cfg?.speed ?? 0);
  72. const desired = new Vec3(toTarget.x * speed, toTarget.y * speed, 0);
  73. this.velocity.x = this.velocity.x + (desired.x - this.velocity.x) * strength;
  74. this.velocity.y = this.velocity.y + (desired.y - this.velocity.y) * strength;
  75. }
  76. }
  77. this.moveLinear(dt);
  78. }
  79. }