对于那些记得Descent Freespace的人来说,它有一个很好的功能,可以帮助你在射击非导弹或激光时瞄准敌人:它在船前显示了一个十字准线,你追逐告诉你在哪里射击,以便击中了移动目标。
我尝试使用来自AI algorithm to "shoot" at a target in a 2d game的答案,但它是针对2D的,所以我尝试调整它。
我首先分解计算以求解XoZ平面的交点并保存x和z坐标,然后求解XoY平面的交点并将y坐标添加到最终的xyz,然后我转换为剪辑空间并放置那些坐标处的纹理。但当然它不能正常工作,否则我就不会发布这个问题了。
从我注意到在XoZ平面中找到x后,在XoY中,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,有一种完全不同的方法?
答案 0 :(得分:1)
如果你(0,0,0)
时t_0 = 0
并以速度pv
射击,并击中一个具有初始位置tp=(tpx,tpy,tpz)
和恒定速度{{1}的目标在时间t,这意味着
tv=(tvx,tvy,tvz)
解决t的这个等式(tp * tv是tp和tv等的标量积):
Abs(tp+t*tv) == t*pv
所以你需要在t = - (tp*tv ± sqrt((tp*tv)^2+(tp * tp)*(pv^2-tv*tv))) / (tv*tv-pv*pv)
的位置进行射击。只需将其投影到视口中并在那里绘制十字准线。
希望这有帮助。
答案 1 :(得分:0)
3D情况的等式与I gave in the 2D case相同。唯一的区别是射击解决方案不是角度形式:你需要3D旋转。但是对于这个应用程序,你不需要一个触发解决方案,你只需要知道在哪里绘制标线。
例如,采用最简单的情况(可以立即旋转的固定式射击游戏):
让目标位于A位置并以速度VA移动,并且射击者在位置B处静止并且可以以速度 s 发射子弹。让射手在时间0开火。子弹击中时间 t 使得| A - B + t VA | = t s 。这是 t 中的二次方程式,您应该能够解决(或确定没有解决方案)。确定 t 后,您现在可以在与子弹击中的世界位置对应的屏幕位置绘制您的标线(即A + t VA)。
其他情况类似,就像在2D中一样。