[英]How to get to an angle choosing the shortest rotation direction
我的游戏中有一个角色必须顺利旋转才能达到理想的角度。 将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)
。 我可能在案件中犯了错误,但这是原则。
通常你想带的时间等式,这样就可以平滑地改变角度可达time
。 大多数设置都有办法获得渲染前一帧所花费的时间,而这样做的典型方法就是说..
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.所以我们向左转。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.