2

背景:我有一个鸟瞰的 JavaScript 游戏,玩家通过触摸一个圆圈来控制宇宙飞船——例如触摸圆圈中心的左侧,飞船会向左移动,触摸右上角它会移动到顶部以此类推……离伪摇杆的圆心越远,那个方向的速度越快。但是,我不是直接调整船的速度,而是设置一个 targetSpeed.x 和 targetSpeed.y 值,然后船将使用以下方式调整其速度:

if (this.speed.x < this.targetSpeed.x) {
    this.speed.x += this.speedStep;
}
else if (this.speed.x > this.targetSpeed.x) {
    this.speed.x -= this.speedStep;
}

...对于 y 速度也是如此,speedStep 是一个较小的值,可以使其更平滑且不会太突然(船只不应从快速向左的方向行驶到立即快速的向右方向)。

我的问题:使用上面的代码,我相信速度会在对角线方向上调整得更快,而在水平/垂直线方向上调整得更慢。如何纠正此问题以具有相同的目标速度跟随?

非常感谢您的帮助!

4

2 回答 2

5
var xdiff = targetSpeed.x - speed.x;
var ydiff = targetSpeed.y - speed.y;
var angle = Math.atan2(ydiff, xdiff);
speed.x += speedStep * Math.cos(angle);
speed.y += speedStep * Math.sin(angle);
于 2010-09-07T14:07:26.643 回答
1

假设您已经检查过触摸在圆圈内,并且圆圈的边缘代表最大速度,并且圆圈的中心是circleTouch == [0, 0]

在一些类似 C++ 的伪代码中:

Scalar circleRadius = ...;
Scalar maxSpeed = ...;
Scalar acceleration = ...;

Vector calculateTargetSpeed( Vector circleTouch ) {
    Vector targetSpeed = maxSpeed * circleTouch / circleRadius;

    return targetSpeed;
}

Vector calculateNewSpeed( Vector currentSpeed, Vector targetSpeed ) {
    Vector speedDiff = targetSpeed - currentSpeed;

    Vector newSpeed = currentSpeed + acceleration * normalized(speedDiff);

    return newSpeed;
}

// Divide v by its length to get normalized vector (length 1) with same x/y ratio
Vector normalized( Vector v ) {
    return v / length(v);
}

// Pythagoras for the length of v
Scalar length( Vector v ) {
    Scalar length = sqrt(v.x * v.x + v.y * v.y); // or preferably hypot(v.x, v.y)

    return length;
}

这只是我的想法,我还没有测试过。另一个答案很好,我只是想给出一个没有三角函数的答案。:)

于 2010-09-07T15:21:51.643 回答