2

对于那些记得 Descent Freespace 的人来说,它有一个很好的功能可以帮助你在射击非归航导弹或激光时瞄准敌人:它在你追逐的船前面显示一个十字准线,告诉你在哪里射击以便击中移动目标。

我尝试使用AI 算法的答案在 2D 游戏中“射击”目标,但它是针对 2D 的,所以我尝试对其进行调整。

我首先分解计算以求解 XoZ 平面的交点并保存 x 和 z 坐标,然后求解 XoY 平面的交点并将 y 坐标添加到最终的 xyz,然后我将其转换为剪辑空间并在那些位置放置纹理坐标。但当然它不能正常工作,否则我不会发布这个问题。

从我注意到在 XoZ 平面和 XoY 中找到 x 后,x 是不一样的,所以一定有问题。

    float a = ENG_Math.sqr(targetVelocity.x) + ENG_Math.sqr(targetVelocity.y) -
            ENG_Math.sqr(projectileSpeed);
    float b = 2.0f * (targetVelocity.x * targetPos.x + 
            targetVelocity.y * targetPos.y);
    float c = ENG_Math.sqr(targetPos.x) + ENG_Math.sqr(targetPos.y);
    ENG_Math.solveQuadraticEquation(a, b, c, collisionTime);

第一次 targetVelocity.y 实际上是 targetVelocity.z(与 targetPos 相同),第二次实际上是 targetVelocity.y。

XoZ 之后的最终位置是

    crossPosition.set(minTime * finalEntityVelocity.x + finalTargetPos4D.x, 0.0f, 
                minTime * finalEntityVelocity.z + finalTargetPos4D.z);

在 XoY 之后

    crossPosition.y = minTime * finalEntityVelocity.y + finalTargetPos4D.y;

我分离成 2 个平面并计算的方法有什么好处吗?或者对于 3D 有完全不同的方法?

  • sqr() 是正方形而不是 sqrt - 避免混淆。
4

2 回答 2

1

如果你(0,0,0)在 timet_0 = 0并且以速度发射弹丸pv并击中在时间 t 具有初始位置tp=(tpx,tpy,tpz)和恒定速度的目标tv=(tvx,tvy,tvz),这意味着

Abs(tp+t*tv) == t*pv

求解 t 的方程(tp*tv 是 tp 和 tv 的标量积等):

t = - (tp*tv ± sqrt((tp*tv)^2+(tp * tp)*(pv^2-tv*tv))) / (tv*tv-pv*pv)

所以你需要在这个位置射击tp+t*tv。只需将其投影到您的视口中并在那里绘制您的十字准线。

希望这可以帮助。

于 2012-10-07T21:15:51.467 回答
0

3D 案例的方程式与我在 2D 案例中给出的方程式相同。唯一的区别是发射解决方案不是角度的形式:您需要 3D 旋转。但是对于这个应用程序,您不需要射击解决方案,您只需要知道在哪里绘制标线即可。

例如,以最简单的情况为例(一个可以立即旋转的静止射手):

设目标在位置 A 并以速度 VA 移动,而射手静止在位置 B 并且可以以速度s发射子弹。让射手在时间 0 开火。子弹在时间t击中,使得 |A - B + t VA| = ts这是t中的二次方程,您应该能够求解(或确定没有解)。确定t后,您现在可以在与子弹将要击中的世界位置(即 A + t VA)相对应的屏幕位置绘制标线。

其他情况类似,就像在 2D 中一样。

于 2012-10-07T21:24:37.210 回答