导弹系统数学问题(极少数代码)

时间:2011-09-01 13:54:24

标签: c# xna

我希望导弹跟随一名遵循以下规则的玩家:
- 当玩家相对于导弹位于右侧时,以固定速率向右更改旋转 - 否则以相同的速率向左更改旋转

            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°位于顶部......)

任何人都可以帮助我吗?

1 个答案:

答案 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
}