| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- 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);
- }
- }
|