|
|
@@ -7,12 +7,11 @@ const { ccclass, property } = _decorator;
|
|
|
*/
|
|
|
|
|
|
export interface BulletTrajectoryConfig {
|
|
|
- type: 'straight' | 'parabolic' | 'arc' | 'homing_arc'; // 弹道类型
|
|
|
- speed: number; // 初始速度
|
|
|
- gravity: number; // 重力影响
|
|
|
- arcHeight: number; // 弧线高度
|
|
|
- homingStrength: number; // 追踪强度 (0-1)
|
|
|
- homingDelay: number; // 追踪延迟(秒)
|
|
|
+ type: 'straight' | 'parabolic' | 'homing'; // 弹道类型
|
|
|
+ speed: number; // 初始速度
|
|
|
+ gravity: number; // 重力影响
|
|
|
+ homingStrength: number; // 追踪强度 (0-1)
|
|
|
+ homingDelay: number; // 追踪延迟(秒)
|
|
|
}
|
|
|
|
|
|
export interface TrajectoryState {
|
|
|
@@ -59,7 +58,7 @@ export class BulletTrajectory extends Component {
|
|
|
this.applyInitialVelocity();
|
|
|
|
|
|
// 寻找目标(用于追踪弹道)
|
|
|
- if (config.type === 'homing_arc') {
|
|
|
+ if (config.type === 'homing') {
|
|
|
this.findTarget();
|
|
|
}
|
|
|
|
|
|
@@ -79,13 +78,18 @@ export class BulletTrajectory extends Component {
|
|
|
break;
|
|
|
|
|
|
case 'parabolic':
|
|
|
- case 'arc':
|
|
|
- case 'homing_arc':
|
|
|
// 计算抛物线初始速度
|
|
|
const velocity = this.calculateParabolicVelocity();
|
|
|
this.rigidBody.linearVelocity = velocity;
|
|
|
this.state.currentVelocity.set(velocity.x, velocity.y, 0);
|
|
|
break;
|
|
|
+
|
|
|
+ case 'homing':
|
|
|
+ this.rigidBody.linearVelocity = new Vec2(
|
|
|
+ this.state.initialVelocity.x,
|
|
|
+ this.state.initialVelocity.y
|
|
|
+ );
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -95,8 +99,8 @@ export class BulletTrajectory extends Component {
|
|
|
private calculateParabolicVelocity(): Vec2 {
|
|
|
// NOTE:
|
|
|
// 1. 当目标位于子弹正上/下方时, 原 direction 的 x 分量可能非常小甚至为 0, 导致 vx≈0, 子弹会几乎垂直运动, 看起来像"钢球"直落。
|
|
|
- // 2. 对于抛物线/弧线弹道, 我们总是希望子弹具备一个最小的水平速度, 并且保证初速度向上( vy>0 ),
|
|
|
- // 这样才能形成明显的抛物或弧线效果并最终击中目标。
|
|
|
+ // 2. 对于抛物线弹道, 我们总是希望子弹具备一个最小的水平速度, 并且保证初速度向上( vy>0 ),
|
|
|
+ // 这样才能形成明显的抛物线效果并最终击中目标。
|
|
|
|
|
|
const rawDir = this.state.initialVelocity.clone().normalize();
|
|
|
|
|
|
@@ -117,7 +121,7 @@ export class BulletTrajectory extends Component {
|
|
|
// 计算纵向初速度, 使得理论最高点接近 arcHeight
|
|
|
// vy = sqrt(2 * g * h)
|
|
|
const g = Math.max(0.1, Math.abs(this.config.gravity * 9.8)); // 避免 g=0 导致除0或 vy=0
|
|
|
- const desiredHeight = Math.max(1, this.config.arcHeight); // 至少 1 避免 0 导致 vy=0
|
|
|
+ const desiredHeight = Math.max(1, 20); // 使用固定高度20作为默认抛物线高度
|
|
|
let vy = Math.sqrt(2 * g * desiredHeight);
|
|
|
|
|
|
// 如果原始方向有明显的向上分量, 为了兼容旧配置, 适当叠加
|
|
|
@@ -183,10 +187,7 @@ export class BulletTrajectory extends Component {
|
|
|
case 'parabolic':
|
|
|
this.updateParabolicTrajectory(dt);
|
|
|
break;
|
|
|
- case 'arc':
|
|
|
- this.updateArcTrajectory(dt);
|
|
|
- break;
|
|
|
- case 'homing_arc':
|
|
|
+ case 'homing':
|
|
|
this.updateHomingTrajectory(dt);
|
|
|
break;
|
|
|
}
|
|
|
@@ -224,29 +225,10 @@ export class BulletTrajectory extends Component {
|
|
|
this.state.currentVelocity.set(currentVel.x, currentVel.y - gravityForce, 0);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 更新弧线弹道
|
|
|
- */
|
|
|
- private updateArcTrajectory(dt: number) {
|
|
|
- // 先应用基础的抛物线逻辑 (受重力影响)
|
|
|
- this.updateParabolicTrajectory(dt);
|
|
|
-
|
|
|
- // 再在垂直方向叠加一个小幅度的正弦扰动, 让轨迹更加圆润。
|
|
|
- const t = this.state.elapsedTime;
|
|
|
- const sinus = Math.sin(t * Math.PI); // [-1,1]
|
|
|
- const extraVy = sinus * this.config.arcHeight * 0.05; // 0.05 系数保证不至于过大
|
|
|
-
|
|
|
- const curVel = this.rigidBody.linearVelocity;
|
|
|
- this.rigidBody.linearVelocity = new Vec2(curVel.x, curVel.y + extraVy);
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 更新追踪弹道
|
|
|
*/
|
|
|
private updateHomingTrajectory(dt: number) {
|
|
|
- // 先按抛物线运动
|
|
|
- this.updateParabolicTrajectory(dt);
|
|
|
-
|
|
|
// 追踪延迟后开始追踪
|
|
|
if (this.homingTimer > 0) {
|
|
|
this.homingTimer -= dt;
|
|
|
@@ -362,7 +344,6 @@ export class BulletTrajectory extends Component {
|
|
|
|
|
|
if (config.speed <= 0) return false;
|
|
|
if (config.gravity < 0) return false;
|
|
|
- if (config.arcHeight < 0) return false;
|
|
|
if (config.homingStrength < 0 || config.homingStrength > 1) return false;
|
|
|
if (config.homingDelay < 0) return false;
|
|
|
|