我希望导弹跟随一名遵循以下规则的玩家:
- 当玩家相对于导弹位于右侧时,以固定速率向右更改旋转
- 否则以相同的速率向左更改旋转
if (missile.Rotation > 0 && missile.Rotation < Math.PI)
{
if (angle > missile.Rotation && angle < missile.Rotation + Math.PI)
{
missile.Rotation += 0.05f;
}
else
{
missile.Rotation -= 0.05f;
}
}
else
{
if (angle < missile.Rotation && angle > missile.Rotation - Math.PI)
{
missile.Rotation -= 0.05f;
}
else
{
missile.Rotation += 0.05f;
}
}
missile.Position += new Vector2((float)(5 * gameTime.ElapsedGameTime.TotalSeconds * Math.Cos(missile.Rotation)), (float)(5 * gameTime.ElapsedGameTime.TotalSeconds * Math.Sin(missile.Rotation)));
有了这个代码,一些导弹似乎有虫子,当我与玩家一起跳跃时,导弹进入一个无法停止的无限循环(它们围成一圈飞行)
坐标系与XNA一样(360°0°位于右侧,270°位于顶部......)
任何人都可以帮助我吗?
答案 0 :(得分:7)
使用欧拉角是一种非常低效的方法。使用矢量要容易得多。
让P成为玩家的位置,让M成为导弹的位置。你需要从这些中计算出两个向量:MP和Mr,其中MP =从导弹到玩家的向量,而Mr是指向导弹右手侧的向量。现在计算向量MP和先生之间的点积。结果的符号告诉你转向导弹的方法。如果它是正的那么顺时针转动导弹,如果它是负的,那么逆时针转动导弹。为什么这样做?
两个向量A和B的点积可写为:
Ax.Bx + Ay.By
还有:
|A|.|B|.cos (theta)
其中theta是两个向量和| x |之间的角度是向量x的大小。这给了我们:
cos (theta) = (Ax.Bx + Ay.By) / (|A|.|B|)
因为我们只想知道值cos(theta)的符号,正值是+ - 90度之间的角度,负值是90到270度之间的角度,我们只需要算出分子的符号,分母总是积极的!因此,点积的符号将告诉我们目标在哪一侧。
但是,你在想,不是比使用角度更难使用的向量吗?我不需要做一些触发功能来计算导弹的右矢量吗?
理想情况下,你根本不应该使用欧拉角。您应该使用矩阵来存储您的世界中对象的位置和旋转。导弹的右向量只是导弹位置/方向矩阵的顶行(或第一列,取决于你如何设置你的系统)。矩阵是渲染硬件用于绘制对象的内容,因此您不会通过使用它们来增加任何开销(事实上,使用角度会增加开销,因为角度符号需要转换为渲染矩阵)。
编辑:您的代码应该看起来像这样:
if (VectorDotProduct (missile.right, player.pos - missil.pos) > 0)
{
missile.rotate clockwise
}
else
{
missile.rotate anti-clockwise
}