如何逐渐旋转物体以面对另一个物体转动最短距离

时间:2011-10-21 08:19:36

标签: c# xna rotation

我正在尝试旋转一个精灵,这取决于它与直接面向目标的程度有多少度(或者rad,我更喜欢度数),问题是当目标到达某个位置时精灵决定旋转完全360到其他方式,而不是做额外的10。这张照片可能更好地解释了这个问题:

Blue square = target, Red square = the object, green line = rotation it wants, black line = current rotation, brown arrow = how it rotates to achieve this, red arrow = how I want it to rotate.

蓝色方块=目标

红色方块=对象

绿线=它想要的旋转

黑线=当前轮换

棕色箭头=如何旋转以实现此目的

红色箭头=我希望它如何旋转。

请注意,情况1始终有效,具体取决于它的旋转方式,但是情况2总是会进行旋转,无论是当前旋转的“右”还是“左”。

这是我用来旋转对象的代码。

    Vector2 distance = new Vector2(target.worldPos.X - this.worldPos.X, target.worldPos.Y - this.worldPos.Y);
    float wantRot = (float)Math.Atan2(distance.Y, distance.X);
    if (this.rotation < wantRot)
        this.rotation += MathHelper.ToRadians(45) * Time.deltaTime;
    if (this.rotation > wantRot)
        this.rotation -= MathHelper.ToRadians(45) * Time.deltaTime;

我想要实现的是根据红色箭头而不是棕色箭头旋转(在案例2中)。

注意:我不是编程方面的专家,我过去一年中不时做过(主要是简单的2D射击游戏/射击游戏),所以深入解释将不胜感激。我也是学生学习编程。

PS:对标题的建议也会受到赞赏,因为我完全不知道该放什么。

1 个答案:

答案 0 :(得分:12)

您的问题是目标可能处于角度5,并且对象可能面向355度(例如)。根据你的测试,5小于355,所以逆时针走。

你应该做的是测试目标是在你的左边180度以内,还是在你的右边180度以内,然后相应地移动。

棘手的部分是让支票围绕360&lt; - &gt;进行'包裹'。 0.看起来你的情况下还剩0度,所以硬测试是针对wantRot在其中有0度的一侧。

要可视化绘制如下所示的圆圈,然后将对象放在我们所面对的位置的左侧。您将看到必须分别检查2个阴影区域。

Visualisation

方法1

单独检查所有案例。

注意:以下代码在我脑海中,未经测试。你需要将度数改为弧度。

int MoveDir = 0;
var BehindMe = this.rotation - 180;
if (BehindMe < 0)
    BehindMe += 360;

if (wantRot != this.rotation)
{
    if (wantRot == BehindMe)
        MoveDir = 1; // or randomly choose
    else if ((wantRot > BehindMe && wantRot < this.rotation) ||
             (this.rotation < 180 && (wantRot > BehindMe ||
                                      wantRot < this.rotation)))
        MoveDir = -1;
    else if ((wantRot < BehindMe && wantRot > this.rotation) ||
             (this.rotation > 180 && (wantRot < BehindMe ||
                                      wantRot > this.rotation))
        MoveDir= 1;

    this.rotation += MoveDir * MathHelper.ToRadians(45) * Time.deltaTime;
}

方法2

从图像中看,你可能会发现你可以检查右边的物体,如果没有,则假设它在左边(因为只要当前角度小于180度检查它在对,很容易)。如果当前角度大于180度,则反转概念 - 检查它是否在左侧,如果不是正确的话。如下所示:

int MoveDir = 0;
var BehindMe = this.rotation - 180;
if (BehindMe < 0)
    BehindMe += 360;

if (wantRot != this.rotation)
{
    if (this.rotation <= 180)
    {
        if (wantRot > this.rotation && wanrRot < BehindMe)
            MoveDir = 1;
        else
            MoveDir = -1;
    }
    else
    {
        if (wantRot < this.rotation && wanrRot > BehindMe)
            MoveDir = -1;
        else
            MoveDir = 1;
    }

    this.rotation += MoveDir * MathHelper.ToRadians(45) * Time.deltaTime;
}