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