如何选择最短旋转方向的角度

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

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

由于您的值在区间[0 360]中始终是标准化的,因此这不应该太难。 您只需要区分两种不同的情况:

 angle < touchAngle angle > touchAngle 

在第一种情况下,我们想要逆时针旋转,因此更新必须是angle =+ 1 (假设您希望每个更新周期转为1)。 在第二种情况下,我们想要顺时针转动,因此更新应该是angle -= 1

问题是这并不总是最短的旋转方式。 例如,如果:

 angle == 359 touchAngle == 1 

我们不想一直使用358,357,356 …而是我们想要逆时针旋转2个单位: abs(angle - touchAngle) 。这可以通过比较角度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)angale != touchAngle) 。 我可能在案件中犯了错误,但这是原则。

通常,您希望为方程带来时间,以便您可以平滑地改变角度。 大多数设置都有办法获得渲染前一帧所花费的时间,而这样做的典型方法就是说..

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

这将使每秒,你的角度由amountToTurnPerSecond改变,但在每帧上缓慢改变正确的变化量,使其平滑。 需要注意的是,大部分时间你都不会在touchAngle均匀地结束,所以检查一下你是否过了而不是设置为touchAngle会是一个好主意。

编辑以跟进评论:

我认为获得正确转弯方向的最简单方法实际上根本就不是使用角度。 您需要在二维空间中获得从触摸到角色的相对方向。 通常你从屏幕空间到世界空间,然后在那里进行计算(至少这是我过去所做的)。 首先触摸世界空间,然后使用矢量十字产品来确定方向。 这看起来有点像以下……

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

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

 dx = tx - cx dy = ty - cy 

这不仅告诉我们离我们有多远,而且基本上告诉我们如果我们在0,0,那么目标在2d空间中的哪个象限?

接下来我们做一个交叉产品:

 cross_product = dx * ry - dy * rx 

如果这是肯定的,你走一条路,如果它是负面的,你去另一条路。 这样做的原因是,如果距离是例如(-5, 2)那么我们知道如果我们正对着北方,那么我们的左边是5,前进是2.所以我们向左转。