java 如何得到一个Angular 选择最短的旋转方向

cotxawn7  于 11个月前  发布在  Java
关注(0)|答案(2)|浏览(139)

我在游戏中有一个角色,必须平滑地旋转才能到达所需的Angular 。考虑angle作为当前Angular ,touchAngle作为所需Angular ,始终在0到360之间。我想添加+1/-1到当前的Angular 在每个游戏更新,以获得所需的touchAngle。问题是,首先它必须选择方向,它必须在0到360.这是我的伪代码:

int touchAngle;
float angle;
public void update()
{
    if ((int)angle != touchAngle) angle += ???
}

字符串

zf9nrax1

zf9nrax11#

因为你的值总是在区间[0 360]内标准化,这应该不会太难。你只需要区分两种不同的情况:

angle < touchAngle
angle > touchAngle

字符串
在第一种情况下,我们想逆时针旋转,所以更新必须是angle =+ 1(假设你想在每个更新周期都转1)。在第二种情况下,我们想顺时针旋转,所以更新应该是angle -= 1
问题是,这并不总是最短的旋转方式。例如,如果:

angle == 359
touchAngle == 1


我们不想一直旋转358,357,356.相反,我们想逆时针旋转2个单位:360,1。这可以通过比较Angular abs(angle - touchAngle)之间的距离来实现。
如果这个值大于180,这意味着我们走错了路,所以我们必须绕过去,

if(angle < touchAngle) {
    if(abs(angle - touchAngle)<180)
       angle += 1;
    else angle -= 1;
}

else {
    if(abs(angle - touchAngle)<180)
       angle -= 1;
    else angle += 1;
}


当然,所有这一切,直到((int)angle != touchAngle)。我可能犯了错误的情况下,但这是原则。

brqmpdu1

brqmpdu12#

一般来说,你想在方程中加入时间,这样你就可以在time上平滑地改变Angular 。大多数设置都有一种方法来获得渲染前一帧所需的时间,典型的方法是说。

int touchAngle;
float angle;
float deltaTime; //Time it took to render last frame, typically in miliseconds
float amountToTurnPerSecond;
public void update()
{
    if((int)angle != touchAngle) angle += (deltaTime * amountToTurnPerSecond);
}

字符串
这将使每秒,你的Angular 是改变了amountToTurnPerSecond,但改变缓慢,每帧的正确数额的变化,使它是平滑的。需要注意的是,你不会均匀地结束在touchAngle的大部分时间,所以检查,看看你去,而不是设置为touchAngle将是一个好主意。
编辑以跟进评论:
我认为获得正确转向方向的最简单方法实际上根本不使用Angular 。您需要在2D空间中获得触摸到角色的相对方向。通常您将触摸从屏幕空间带到世界空间,然后在那里进行计算(至少这是我过去做的)。首先让你的触摸进入世界空间,然后使用矢量叉积来确定方向。这看起来有点像下面的.

character position = cx, cy
target position = tx, ty
current facing direction of character = rx, ry


首先,我们计算角色和目标位置之间的距离:

dx = tx - cx
dy = ty - cy


这不仅告诉我们它离我们有多远,而且本质上告诉我们,如果我们在0,0,目标会在二维空间的哪个象限?
接下来我们做一个cross product:

cross_product = dx * ry - dy * rx


如果它是正的,你走这条路,如果它是负的,你走另一条路,原因是,如果距离是,例如,(-5, 2),那么我们知道,如果我们直接面向北方,点是在我们的左边,然后向前,所以我们左转。

相关问题