我正在编写一个小游戏很长一段时间。我们开始在学校的项目中编写一个小型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
Variabledefinition
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)* speed + 0.5 * gravity * time * time
pos(t).x和pos(t).z不确定如何计算(x和z)基本上定义前进方向..不仅仅是x ..
在不知道时间的情况下无法计算敌人..我无法计算时间而不知道角度(θ,俯仰/偏航)以及它与“未来”撞击点的距离
答案 0 :(得分:0)
首先,当您使用C ++时,非常值得使用重载算术运算符,因此广泛使用向量运算。你的公式看起来会更清晰,更接近数学定义。您很少需要明确的.x
,.y
分配。
现在问你的问题:
主要问题是我无法计算碰撞时的敌人位置,因为我没有时间过去直到发生碰撞
是的,时间是要走的路。
想象一下,你在同一时间向各个方向射击。在任何给定时间,所有射弹都将在空中的某个地方形成一个膨胀的球体。现在,您可以将此球体与目标的路径相交,并在发生命中时获得次。这样的数学有点棘手(求解四度的多项式方程),但它适用于近似。
因为你是德国人,所以你一定要看看这个涵盖这个主题的德语article!
答案 1 :(得分:0)
不是一个完整的解决方案,而是我如何从一个数学的角度来看待它。
您想要遇到两个对象。你需要找到的三个未知数是命中发生的时间,垂直射击角度和水平射击角度。
您只需说出
即可知道目标在任何时间的位置position = initial position + t*velocity
(在这里的矢量中)。
射弹的位置将是:
position = initial position + t*(initial velocity) + 0.5*acceleration*t^2
(再次向量,所以这里的初始速度将取决于镜头的两个角度)
当我们得到一个明显的命中时,这两个位置将是相同的,所以我们可以将这两个位置等同。
我们知道有一个有效的三个未知数的向量方程。如果我们然后将它分成它的分量向量,则这些方程中的每一个仅适用于向量的x,y和z分量(注意,加速度仅在z方向上具有分量)。
然后我们得到三个具有三个未知数的方程式,这些方程式将同时求解。我要把剩下的留给你的主要原因是因为我不知道如何以一种很好的方式在我的答案中代表代数。 :)
对不起,这不是更完整,但希望可能会给你一种新的方式来看待事物,你可能自己通过数学来自己解决方程式(不难但同时也不那么容易)。 ..)
答案 2 :(得分:0)
如果敌人以恒定速度行走(即直线行进),最简单的方法是改变变量,以便在敌人的移动框架中写下所有内容。然后,你有一个二次方程来解决。
但在现实世界中,有许多敌人,当你射击时,你必须测试你的子弹在时间t是否与某些敌人的形状相交(敌人不是点)。所以你发射你的子弹,用快速ODE求解器模拟它的轨迹:Runge Kutta 4阶是常用的,我认为,不是因为它的准确性(你没有简单的错误控制,你不需要物理准确性:只有现实主义。不要使用RK4来解决除视频游戏之外的ODE,而是因为你可以采取相对较长的时间步而不会太过分。
实际上,模拟游戏的物理特性(玩家和敌人的物理和IA,子弹......)需要你跟踪时间。然后迭代子弹并测试它们与游戏的各种对象(主要是敌人)的交集。
每次计算交叉点的典型方法是使用八叉树来跟踪对象的位置。在给定时间,此设备使您可以轻松地(记录)与子弹位于相同空间区域的敌人。现在,您可以使用: