XNA运动物理与跟踪

本文关键字:跟踪 运动 XNA | 更新日期: 2023-09-27 18:26:08

所以,我有一个正在制作的游戏,遇到了一个障碍。我有两个精灵,称它们为A和B。到目前为止,我一直让A非常简单地跟踪B:获取B的位置,如果它的X坐标大于A的X坐标,则将A的速度添加到它的X位置。对小于A的X位置和Y位置重复上述步骤。我也有一个指向,通过存储它的旧位置,并使用一些简单的三角法设置旋转。然而,现在我已经完成了所有其他工作,我想让这件事更现实一点。当B从a的左点快速移动到a的右点时,a的角度和移动从指向和从左下到右下快速跳跃。我需要它平稳地移动。我想放慢A改变角度的速度(比如说,每次Update()调用可能5度),但这并不能解决问题,我只会让A横向移动一段时间。我意识到这是一个很长的问题,我可能不会得到很多答案,但你们能说的任何话都会有很大帮助。谢谢

XNA运动物理与跟踪

我认为您正在寻求建立一个捕食者-猎物系统。这些通常用微分方程建模,但这里有一个简单的模拟算法。

我建议lerping(线性插值)A随时间对B的跟踪,而不是立即跟踪。将Vector2存储在A上,即它实际面对的位置,并在每帧向B倾斜一定的量,无论是硬编码角度还是一定的百分比。

下面是一些将当前位置向所需位置倾斜的示例代码。

Vector3 current = Vector3.Zero;
Vector3 desired = new Vector3(10, 0, -5);
// For this example we will lerp 75% of the way from 'current' to 'desired' per second
Vector3 LerpTowardDesired( Vector3 current, Vector3 desired, float timeDelta )
{
    float lerpPercentage = timeDelta * 0.75f;
    Vector3 newPos = Vector3.Zero;
    newPos.x = MathHelper.Lerp(current.x, desired.x, lerpPercentage);
    newPos.y = MathHelper.Lerp(current.y, desired.y, lerpPercentage);
    newPos.z = MathHelper.Lerp(current.z, desired.z, lerpPercentage);
}

在上面的示例中,您只需每帧调用LerpTowardDesired一次,将经过的时间(以秒为单位)作为timeDelta传入。请注意,timeDelta是一个浮点值,因此传入的秒包括部分秒(例如,0.016表示1/60秒,因此不会四舍五入到最接近的秒并传入0)。

使用我们上面定义的currentdesired矢量,这就是在几帧的过程中的结果,假设完美的60fps(每秒帧数)。

// After frame 1
current = LerpTowardDesired(current, desired, 0.016f);
// current is now (0.12f, 0.0f, -0.06f)
// After frame 2
current = LerpTowardDesired(current, desired, 0.016f);
// current is now (0.239f, 0.0f, -0.119f)
// After frame 3
current = LerpTowardDesired(current, desired, 0.016f);
// current is now (0.356f, 0.0f, -0.178f)

正如您在3帧中看到的,current位置已开始向desired位置移动。如果你让你的精灵总是面对current的位置,他应该随着时间的推移而不是立即跟踪目标精灵。

使用百分比而不是每帧硬编码的度数进行预警的最好方法是,目标移动得越快,预警发生得就越快,因为在更大的距离中,这将是相同的百分比。这意味着A将始终跟上B,无论它走得多快。