我正在编写一个星舰游戏,刚刚完成了管理旋转的部分。我使用简单的if / else语句检查船舶是否必须旋转正或负,以便尽快面对目标。但是我看到旋转值可以变为负值,然后船会旋转到错误的方向(它最终仍面向目标点,但需要更长时间)。请告诉我我做错了什么:(
功能:
public bool RotateOrMove(Vector2 position)
{
if (IsRotationg == null) //todo
{
Vector2 direction = Position - position;
direction.Normalize();
FinalRotation = (float)Math.Atan2(-direction.X, direction.Y);
IsRotationg = true;
}
if (Equals(FinalRotation, Rotation))
IsRotationg = false;
if (IsRotationg == false)
{
Position = position;
return true;
}
else
{
if (FinalRotation >= Rotation)
{
Rotation += RotationVelocity;
if (FinalRotation - Rotation < RotationVelocity)
{
Rotation = FinalRotation;
IsRotationg = false;
}
}
if (FinalRotation < Rotation)
{
Rotation -= RotationVelocity;
if (FinalRotation - Rotation > -RotationVelocity)
{
Rotation = FinalRotation;
IsRotationg = false;
}
}
return false;
}
}
玩家级别拥有该船。当玩家按下鼠标右键时,每帧会调用一次此方法,直到船到达光标指向的位置。
if (!Ship.RotateOrMove(Position))
Position -= Velocity;
因此,如果船舶必须旋转且无法移动,它将移除它之前刚刚添加的速度,以确保船舶不会移动。
希望你理解我的问题^^
答案 0 :(得分:1)
Math.Atan2将值从-pi返回到pi。
要获得平滑的旋转,您可以使用从here
获取的代码private float CurveAngle(float from, float to, float step)
{
if (step == 0) return from;
if (from == to || step == 1) return to;
Vector2 fromVector = new Vector2((float)Math.Cos(from), (float)Math.Sin(from));
Vector2 toVector = new Vector2((float)Math.Cos(to), (float)Math.Sin(to));
Vector2 currentVector = Slerp(fromVector, toVector, step);
return (float)Math.Atan2(currentVector.Y, currentVector.X);
}
private Vector2 Slerp(Vector2 from, Vector2 to, float step)
{
if (step == 0) return from;
if (from == to || step == 1) return to;
double theta = Math.Acos(Vector2.Dot(from, to));
if (theta == 0) return to;
double sinTheta = Math.Sin(theta);
return (float)(Math.Sin((1 - step) * theta) / sinTheta) * from + (float)(Math.Sin(step * theta) / sinTheta) * to;
}