import { _decorator, Component, Node, Vec3 } from 'cc'; import { BulletTrajectoryConfig } from '../BulletTypes'; const { ccclass } = _decorator; /** * 弹道控制(可移植版) * - straight:匀速直线 * - arc:带重力或弧线(简化为重力) * - guided:简单追踪(需要调用 setTarget 或外部提供方向更新) */ @ccclass('BCBulletTrajectory') export class BulletTrajectory extends Component { private cfg: BulletTrajectoryConfig | null = null; private velocity: Vec3 = new Vec3(0, 0, 0); private target: Node | null = null; private homingTimer = 0; private origin: Vec3 = new Vec3(); public init(cfg: BulletTrajectoryConfig, direction: Vec3, startPos: Vec3, originNode?: Node | null) { this.cfg = { ...cfg }; const speed = Math.max(0, this.cfg.speed ?? 0); const dir = direction?.clone() ?? new Vec3(1, 0, 0); if (dir.length() === 0) dir.set(1, 0, 0); dir.normalize(); this.velocity.set(dir.x * speed, dir.y * speed, 0); this.node.setPosition(startPos); this.origin.set(startPos); this.homingTimer = 0; } public setTarget(node: Node | null) { this.target = node; } public getCurrentVelocity(): Vec3 { return this.velocity.clone(); } update(dt: number) { if (!this.cfg) return; const type = this.cfg.type; if (type === 'straight') { this.moveLinear(dt); } else if (type === 'arc') { this.moveArc(dt); } else if (type === 'guided') { this.moveGuided(dt); } else { this.moveLinear(dt); } } private moveLinear(dt: number) { const dx = this.velocity.x * dt; const dy = this.velocity.y * dt; const p = this.node.position; this.node.setPosition(p.x + dx, p.y + dy); } private moveArc(dt: number) { const g = this.cfg?.gravity ?? 0; // 简化:重力沿 y 轴正方向(向下) this.velocity.y -= g * dt; this.moveLinear(dt); } private moveGuided(dt: number) { const delay = Math.max(0, this.cfg?.homingDelay ?? 0); this.homingTimer += dt; if (this.homingTimer >= delay && this.target && this.target.isValid) { const pos = this.node.worldPosition; const tpos = this.target.worldPosition; const toTarget = new Vec3(tpos.x - pos.x, tpos.y - pos.y, 0); const dist = toTarget.length(); if (dist > 1e-3) { toTarget.normalize(); const strength = Math.max(0, Math.min(1, this.cfg?.homingStrength ?? 0)); // 插值改变速度方向,但保持速率(magnitude)接近 cfg.speed const speed = Math.max(0, this.cfg?.speed ?? 0); const desired = new Vec3(toTarget.x * speed, toTarget.y * speed, 0); this.velocity.x = this.velocity.x + (desired.x - this.velocity.x) * strength; this.velocity.y = this.velocity.y + (desired.y - this.velocity.y) * strength; } } this.moveLinear(dt); } }