在3D游戏中向目标射击的算法


11

对于那些想起“下降自由空间”的人来说,它有一个不错的功能,可以帮助您在射击非归巢的导弹或激光时瞄准敌人:它在您追赶的船前显示了十字准线,告诉您在哪里射击才能击中移动的物体。目标。

我尝试使用来自/programming/4107403/ai-algorithm-to-shoot-at-a-target-in-a-2d-game?lq=1的答案,但它适用于2D,所以我尝试了适应它。

我首先分解计算以求解XoZ平面的交点并保存x和z坐标,然后求解XoY平面的交点,然后将y坐标添加到最终的xyz中,然后将其转换为剪贴空间并在其上放置纹理坐标。但是,它当然不能正常运行,否则我就不会提出这个问题。

根据我的发现,在XoZ平面中找到x和在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;

我的方法分为两个平面并计算出任何效果吗?还是3D有完全不同的方法?

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

1
“领先目标”可能是您要寻找的短语。
MichaelHouse

Answers:


12

无需将其分解为2个2d函数。您正在使用的二次方程在3d中也能正常工作。这是2d或3d的伪代码。这意味着塔(塔防)正在发射弹丸:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second 

“ aimSpot”可能是您要问的载体。


你是个天才,救了我的屁股!!该死,我需要15点声望才能
投票。...–塞巴斯蒂安·布久

@SebastianBugiu我为你做了。
AgentFire

@SebastianBugiu谢谢,当我了解这个概念时感到很高兴,并很高兴它为您提供了帮助。它的另一个优雅功能是,您无需弄乱碰撞检测算法。无需编写CD代码。由于目标和射弹的路径是可预测的,因此当timeToImpact倒数至零时,会产生影响。
史蒂夫·H

1

关于同一主题,还有一篇不错的博客文章:http : //playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html。它还包含更复杂的样本,其中包括重力。

作者做了更多简化,从而使代码更紧凑:

double time_of_impact(double px, double py, double vx, double vy, double s)
{
    double a = s * s - (vx * vx + vy * vy);
    double b = px * vx + py * vy;
    double c = px * px + py * py;

    double d = b*b + a*c;

    double t = 0;
    if (d >= 0)
    {
        t = (b - sqrt(d)) / a;
        if (t < 0) 
        {
            t = (b + sqrt(d)) / a;
            if (t < 0)
                t = 0;
        }
    }

    return t;
}

更新:原始作者只考虑了更大的根源。但是,如果较小的根为非负数,则由于影响时间较小,因此可以提供更好的解决方案。我已经相应地更新了代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.