C++ AI 轮换问题
C++ AI Rotation Issue
对于我正在制作的游戏,我想要 3 艘船,它们将按照一系列积分在地图上竞速。它工作得很好,除了地图上的一个点,船只决定逆时针旋转近 360 度,即使顺时针旋转 10 度就足够了。
计算旋转的代码:
vec2 distance = *desiredPosition - position;
float rot = atan2(distance.y, distance.x);
rot = rot * 180.f / PI + 90.f;
if (rot < angle)
{
angle -= dAngle;
boat->RotateImage(-dAngle);
}
if (rot > angle)
{
angle += dAngle;
boat->RotateImage(dAngle);
}
velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));
如何确保它不会在那里旋转错误的方向?
感谢 Richard Byron(接受以下答案),问题已解决。取点积比用度数好。
最终代码:
vec2 distance = desiredPosition - position;
normal = vec2(sin((angle - 90) * PI / 180.0), cos((angle - 90) * PI / 180.0) * -1);
float dir = normal.x * distance.x + normal.y * distance.y;
//turn
if (dir > 0)
{
angle -= dAngle;
boat->RotateImage(-dAngle);
}
if (dir < 0)
{
angle += dAngle;
boat->RotateImage(dAngle);
}
velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));
无论顺时针还是逆时针,船的转弯角度都应小于 180 度。如果它在一个方向上转动超过 180 度,那么转向另一个方向会更好。
一个更通用的解决方案是计算相对于船参考系的距离矢量。
您的更新代码存在一些问题。首先,它应该是 rot2 = 360 - rot1; (rot1 + 360 与rot1 完全相同的角度)。
第二个问题是你没有考虑到1度和359度几乎是同一个角度。所以如果 abs(rot1 - angle) > 180,那么在这种情况下你真的想使用 360 - abs(rot1 - angle)。出于同样的原因,您后来与 rot 和 angle 的比较也是一个问题,您需要处理角度在 360 以上递增和在 0 以下递减。
我可以为此写出代码,但实际上有一种更简单、更快捷的方法可以做到这一点。如果您将向量 (desiredPosition - position) 与与船舶当前航向成直角的向量进行点积,则您可以根据该结果的符号转弯。如果不清楚如何执行此操作,请告诉我,我可以在评论中对其进行扩展。
对于我正在制作的游戏,我想要 3 艘船,它们将按照一系列积分在地图上竞速。它工作得很好,除了地图上的一个点,船只决定逆时针旋转近 360 度,即使顺时针旋转 10 度就足够了。
计算旋转的代码:
vec2 distance = *desiredPosition - position;
float rot = atan2(distance.y, distance.x);
rot = rot * 180.f / PI + 90.f;
if (rot < angle)
{
angle -= dAngle;
boat->RotateImage(-dAngle);
}
if (rot > angle)
{
angle += dAngle;
boat->RotateImage(dAngle);
}
velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));
如何确保它不会在那里旋转错误的方向?
感谢 Richard Byron(接受以下答案),问题已解决。取点积比用度数好。
最终代码:
vec2 distance = desiredPosition - position;
normal = vec2(sin((angle - 90) * PI / 180.0), cos((angle - 90) * PI / 180.0) * -1);
float dir = normal.x * distance.x + normal.y * distance.y;
//turn
if (dir > 0)
{
angle -= dAngle;
boat->RotateImage(-dAngle);
}
if (dir < 0)
{
angle += dAngle;
boat->RotateImage(dAngle);
}
velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));
无论顺时针还是逆时针,船的转弯角度都应小于 180 度。如果它在一个方向上转动超过 180 度,那么转向另一个方向会更好。
一个更通用的解决方案是计算相对于船参考系的距离矢量。
您的更新代码存在一些问题。首先,它应该是 rot2 = 360 - rot1; (rot1 + 360 与rot1 完全相同的角度)。
第二个问题是你没有考虑到1度和359度几乎是同一个角度。所以如果 abs(rot1 - angle) > 180,那么在这种情况下你真的想使用 360 - abs(rot1 - angle)。出于同样的原因,您后来与 rot 和 angle 的比较也是一个问题,您需要处理角度在 360 以上递增和在 0 以下递减。
我可以为此写出代码,但实际上有一种更简单、更快捷的方法可以做到这一点。如果您将向量 (desiredPosition - position) 与与船舶当前航向成直角的向量进行点积,则您可以根据该结果的符号转弯。如果不清楚如何执行此操作,请告诉我,我可以在评论中对其进行扩展。