1

我正在编写一个小游戏很长一段时间。我们开始在学校的一个项目中编写一个小型 FPS-Shooter,以获得一些使用 directX 的经验。我不知道为什么,但我无法停止该项目并开始在家编程。目前我正在尝试创建一些小型 AI。当然,这绝对不容易,但那是我的个人目标。该主题可能会填满多本书,呵呵。到目前为止,我已经完成了我的机器人的行走部分。他们沿着一条刻划的小路行走。我不是在研究机器人的“瞄准”。在编程时,我遇到了一些我还无法解决的数学问题。我希望你的意见能帮助我走得更远。概念、想法和其他一切都受到高度赞赏。

问题:计算弹丸曲线(取决于重力、速度)的位置(D3DXVECTOR3),击中敌人行走路径的曲线(取决于速度)。我们假设敌人走在一条恒定的路线上。

已知变量:

float projectilSpeed = 2000 m/s //speed of the projectile per second
float gravitation = 9.81 m/s^2 //of cause the gravity lol
D3DXVECTOR3 targetPosition //position of the target stored in a vector (x,y,z)
D3DXVECTOR3 projectilePosition //position of the projectile
D3DXVECTOR3 targetSpeed //stores the change of the targets position in the last second

变量定义

ProjectilePosition at time of collision = ProjectilePos_t
TargetPosition at time of collision = TargetPos_t
ProjectilePosition at time 0, now = ProjectilePos_0
TargetPosition at time 0, now = TargetPos_0
Time to impact = t
Aim-angle = theta

我的尝试:在维基百科上找到了一个计算“下落”(基于重力的弹丸下落)的公式:

float drop = 0.5f * gravity * t * t

弹丸的速度有水平部分和垂直部分。在维基百科上也找到了一个公式:

ProjectilVelocity.x = projectilSpeed * cos(theta)
ProjectilVelocity.y = projectilSpeed * sin(theta)

所以我认为这对于弹丸曲线是正确的:

ProjectilePos_t.x = ProjectilePos_0.x + ProjectileSpeed * t
ProjectilePos_t.y = ProjectilePos_0.y + ProjectileSpeed * t + 0.5f * gravity * t * t
ProjectilePos_t.z = ProjectilePos_0.z + ProjectileSpeed * t

目标以恒定的速度行走,因此我们可以通过以下方式确定他的曲线:

TargetPos_t = TargetPos_0 + TargetSpeed * D3DXVECTOR3(t, t, t)

现在我不知道如何继续。我必须以某种方式解决它,以抓住时间以某种方式产生影响。作为一个基本公式,我可以使用:

float time = distanz / projectileSpeed

但这不会是真正正确的,因为它会假设一个线性的“轨迹”。我们只是在使用火箭时才发现这种行为。

我希望我能够尽可能地解释这个问题。如果还有问题,请随时问我!

来自德国的问候,弗兰克


编辑:

主要问题是我无法计算碰撞时的敌人位置,因为直到碰撞发生之前我没有时间过去。另一方面,我无法在不知道碰撞时敌人位置的情况下计算时间。也许迭代方法可以解决这个问题。

曲线敌人:

pos(t).x = pos(0).x + speed.x * time
pos(t).y = pos(0).y + speed.y * time
pos(t).z = pos(0).z + speed.z * time

曲线弹丸:pos(t).y = pos(0).y ​​+ sin(theta) * 速度 + 0.5 * 重力 * 时间 * 时间

pos(t).x 和 pos(t).z 不确定如何在 (x 和 z) 中计算基本上定义了前向.. 不仅仅是 x..

在不知道时间的情况下无法计算敌人..我无法在不知道角度(θ、俯仰/偏航)以及到“未来”撞击点的距离的情况下计算时间

4

3 回答 3

0

不是一个完整的解决方案,而是我将如何从数学的角度来解决这个问题。

您有两个想要满足的对象。您需要找到的三个未知数是击球发生的时间、垂直射门角度和水平射门角度。

随时知道目标的位置 t 只要说

position = initial position + t*velocity

(这里的向量)。

弹丸的位置将是:

position = initial position + t*(initial velocity) + 0.5*acceleration*t^2

(再次向量,所以这里的初始速度将取决于镜头的两个角度)

当我们受到打击时,显然这两个位置将是相同的,因此我们可以将这两个位置等同起来。

我们知道有效地有一个具有三个未知数的向量方程。如果我们然后将其拆分为其分量向量,则这些方程中的每一个仅适用于向量的 x、y 和 z 分量(请注意,加速度仅在 z 方向上具有分量)。

然后我们得到三个方程,三个未知数将同时求解。我将其余部分留给您的主要原因是因为我不知道如何以一种很好的方式在我的答案中表示代数。:)

抱歉,这不是更完整,但希望可以为您提供一种看待事物的新方式,并且您可能能够自己通过数学来解决方程(不难,但同时也不是那么容易......)

于 2010-12-30T12:00:06.243 回答
0

首先,当您使用 C++ 时,非常值得使用重载的算术运算符,因此广泛使用向量运算。您的公式将看起来更清晰,更接近数学定义。你根本不需要显式.x.y赋值。

所以现在回答你的问题:

主要问题是我无法在碰撞时计算敌人的位置,因为我没有时间过去直到碰撞发生

是的,时间就是要走的路。

想象一下,你同时朝所有可能的方向射击。在任何给定时间,所有射弹都会在空中某处形成一个膨胀的球体。您现在可以将此球体与目标的路径相交,并获取可能发生命中的时间。这方面的数学有点棘手(求解四次多项式方程),但它适用于近似值。

由于您是德国人,因此您绝对应该看看这篇很好地涵盖了该主题的德语文章!

于 2010-12-30T11:40:50.073 回答
0

如果敌人以恒定的速度行走(即直线),最简单的方法是更改​​变量,以便将所有内容都写入敌人的移动框架中。然后,你有一个二次方程要求解。

但是在现实世界中,敌人很多,而且你在射击的时候,要测试你在t时刻的子弹是否与某个敌人的形状相交(敌人不是点)。所以你发射子弹,用快速 ODE 求解器模拟它的轨迹:我认为 Runge Kutta 4 阶是常用的,而不是因为它的准确性(你无法轻松控制错误,而且你不需要物理精度:只有现实主义。不要使用 RK4 来解决 ODE,除非在视频游戏中)但是因为您可以采取相对较大的时间步长而不会太偏离。

实际上,模拟游戏的物理特性(玩家和敌人的物理特性以及 IA、子弹……)需要您跟踪时间。然后迭代子弹并测试它们与游戏的各种对象(主要是敌人)的交集。

每次,计算交点的典型方法是使用八叉树来跟踪对象的位置。在给定时间,此设备使您能够轻松定位 (log n) 与子弹位于同一空间区域的敌人。现在,您可以使用:

  • 为敌人设置边界基本形状(盒子、球体),在子弹击中或未击中敌人时处理很多情况:将盒子放在敌人形状的外部和内部。
  • 当边界框什么都不告诉你时(你通过一个外框,但不与任何内框相交),你必须计算出一条小直线的交点(在 t 和 t + dt 之间,dt 不那么小)敌人的形状。
于 2010-12-30T12:53:29.860 回答