feat(skill): 改进贝塞尔曲线弹道运动实现
- 为技能配置添加贝塞尔曲线参数控制:起始高度、中间高度和弧度系数 - 重构贝塞尔曲线控制点计算逻辑,移除冗余的水平投影计算 - 优化控制点生成算法,考虑距离、弧度系数和最小峰值高度 - 增加速度安全检查和最小时间限制,避免除零和异常情况 - 将多个射击技能从直线运动改为贝塞尔曲线运动,提供更自然的弹道效果
This commit is contained in:
@@ -65,6 +65,9 @@ export class SMoveDataComp extends ecs.Comp {
|
||||
|
||||
/** 贝塞尔曲线控制点 */
|
||||
controlPoint: Vec3 = v3(0, 0, 0);
|
||||
bezierStartHeight: number = 18;
|
||||
bezierMidHeight: number = 140;
|
||||
bezierArc: number = 1;
|
||||
|
||||
/** 是否自动销毁(到达目标后) */
|
||||
autoDestroy: boolean = true;
|
||||
@@ -74,6 +77,9 @@ export class SMoveDataComp extends ecs.Comp {
|
||||
this.targetPos.set(0, 0, 0);
|
||||
this.currentPos.set(0, 0, 0);
|
||||
this.controlPoint.set(0, 0, 0);
|
||||
this.bezierStartHeight = 18;
|
||||
this.bezierMidHeight = 140;
|
||||
this.bezierArc = 1;
|
||||
this.speed = 500;
|
||||
this.progress = 0;
|
||||
this.scale = 1;
|
||||
@@ -109,7 +115,8 @@ export class SMoveDataComp extends ecs.Comp {
|
||||
*/
|
||||
private calculateMoveParameters() {
|
||||
const distance = Vec3.distance(this.startPos, this.targetPos);
|
||||
this.totalTime = distance / this.speed;
|
||||
const safeSpeed = Math.max(1, this.speed);
|
||||
this.totalTime = Math.max(0.05, distance / safeSpeed);
|
||||
|
||||
// 为贝塞尔移动生成控制点
|
||||
if (this.runType === RType.bezier) {
|
||||
@@ -127,12 +134,25 @@ export class SMoveDataComp extends ecs.Comp {
|
||||
// 计算垂直方向
|
||||
const direction = new Vec3();
|
||||
Vec3.subtract(direction, this.targetPos, this.startPos);
|
||||
if (direction.length() < 0.0001) {
|
||||
this.controlPoint.set(midPoint.x, midPoint.y + this.bezierMidHeight, midPoint.z);
|
||||
return;
|
||||
}
|
||||
const perpendicular = v3(-direction.y, direction.x, 0);
|
||||
perpendicular.normalize();
|
||||
|
||||
// 根据scale决定控制点方向
|
||||
const offset = 100 * this.scale;
|
||||
const distance = Vec3.distance(this.startPos, this.targetPos);
|
||||
const baseOffset = Math.max(120, Math.min(220, distance * 0.35));
|
||||
const offset = baseOffset * Math.max(0.2, this.bezierArc);
|
||||
if (perpendicular.y < 0) {
|
||||
perpendicular.x *= -1;
|
||||
perpendicular.y *= -1;
|
||||
}
|
||||
Vec3.scaleAndAdd(this.controlPoint, midPoint, perpendicular, offset);
|
||||
const minPeakY = midPoint.y + Math.max(0, this.bezierMidHeight);
|
||||
if (this.controlPoint.y < minPeakY) {
|
||||
this.controlPoint.y = minPeakY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user