2D塔防-敌人的子弹


14

我正在尝试找到一种好的方法来解决子弹击中敌人的问题。游戏是2D塔防,塔应该发射子弹并保证击中敌人。

我尝试了这种解决方案-http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

提到的链接也要减去子弹的起源和敌人(矢量减法)。我试过了,但子弹刚好绕过敌人。

float diffX = enemy.position.x - position.x;
float diffY = enemy.position.y - position.y;

velocity.x = diffX;
velocity.y = diffY;

position.add(velocity.x * deltaTime, velocity.y * deltaTime);

我对向量很熟悉,但不确定要使此解决方案有效需要执行哪些步骤(向量数学运算)。


Answers:


11

您的推理是完美的:使用向量从我的位置移动到目标。这是向量的目的; 您根本忘记了速度

速度是一个向量:速度和方向。但是,如果忘记标准化差向量并将其乘以子弹速度(标量),则基本上是在说,如果您靠近目标(差向量很小),则子弹会变慢;而如果您距离较远,子弹速度会更大。

这是潜在的问题:您需要计算向量的方向大小。


感谢您的帮助。在计算差值向量后,我尝试使用标量,它看起来很有效,但是效果不好。我试图查看是否要计算差矢量,进行归一化,然后对速度进行标量。现在看起来更好。是的,我想我稍后需要在这款游戏中使用寻的导弹。再次感谢。
塔舒

1
这个答案对其他人没有意义吗?
BlueRaja-Danny Pflughoeft 2011年

@Fxlll:好的,我想我明白你要说的。开始/结束时有很多与答案无关的绒毛,您的英语也让我感到困惑(我意识到这可能不是您的错)。我已经提交了修改建议,以清理此答案。
BlueRaja-Danny Pflughoeft 2011年

@BlueRaja-Danny Pflughoeft感谢您的努力!
FxIII 2011年

7

如果目标以稳定的速度沿稳定的方向移动,并且子弹路径以稳定的速度沿直线移动,则可以使用二次方程式来预测它们将相交的确切点,并将塔的枪对准该点。

由于可以确定子弹会击中其标记,并且您可以计算出从发射到撞击所需的确切时间,因此无需碰撞检测,只需开枪,等待计算出的时间跨度,记录一次击中即可。

这是二次方程式的伪代码:

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

感谢您提供的伪代码,我将对其进行检查,以查看二次方程在这种情况下如何工作。再次感谢。
塔舒

问题是用户可能会朝子弹移动,而在被击中之前,他可能会摆脱子弹的痕迹。在这种情况下,这种解决方案是否足够好?
马丁。

否,因为第一句中有限定。这并非适用于所有游戏,而是适用于目标仅以恒定速度运动的游戏。恒定速度意味着方向和速度。例如,防御网格风格的游戏可以使用这种方法。
史蒂夫·H

3

您需要在子弹到达时“预测”物体的位置。您可以使用物体的速度/速度(希望是常数;)和它的方向向量来实现。

我不确定确切的公式是什么,但我认为它是这样的:

NewPosition = OldPosition +(速度* DirectionVector);

如果您有设置的路径,则当对象改变方向时需要重新计算。使用此NewPosition作为您的敌人。位置矢量,子弹应击中对象而没有“归位效果”。归巢是由于自从计算原始向量以来敌对物体已移动的事实而发生的,它只能在物体沿一个方向行进足够长的时间时才追赶。

希望这可以帮助 :)


3
或者,您可以作弊并自动击中,然后将移动的精灵用作视觉反馈。或者只是以50000²mph的速度发射子弹。
乔纳森·康奈尔

1

您可以避免使用平方根和2的幂。

var distX:Float = target.x - x;
var distY:Float = target.y - y;
_velX = distX / timeTravel;
_velY = distY / timeTravel;

// Take out if you want a nice slow down as approaches effect.  
timeTravel -= 1.0; // make sure u have a positive timeTravel.
x += _velX;
y += _velY;

if (distX < 0)
    distX = -distX;

if (distY < 0)
    distY = -distY;

if (_velX < 0)
    _velX = -_velX;

if (_velY < 0)
    _velY = -_velY;

// Should both snap @ the same time.
if (distX < _velX)
x = target.x; // snap & see what happens.

if (distY < _velY)
y = target.y; // snap & see what happens.

// TODO: call your onHitTarget here ...
// Hopefully this shall provide 10x the performance 
// of using Math.sqrt and all the extra multiplications.

这些都是从内存中写入的。顺便说一下,使用有效的元素-如果您是新手,请逐行对其进行测试。浮点数是AS3中的数字。

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.