2D游戏算法计算子弹射击目标所需的速度?

时间:2010-07-09 09:26:34

标签: javascript math graphics geometry 2d

我有一个相当简单的鸟瞰2D游戏,其中塔精灵通过向他们射击子弹来防御传入的移动精灵。我的问题:如果子弹总是具有相同的定义速度,我如何计算子弹到达其移动目标所需的子弹速度?

我正在使用JavaScript并拥有这些精灵变量(以及其他): sprite.x,sprite.y,sprite.width,sprite.height,sprite.speedX(即velocity),sprite.speedY ...所以我有对象originSprite,targetSprite和bulletSprite,都有这些类型的值,而我需要设置正确的bulletSprite速度值。

可能它看起来不错,子弹将从originSprite的外部开始(或者一些定义的半径,虽然我想从originSprite中心开始也可以工作),但它的子弹中心会尝试击中它的中心targetSprite左右。请注意,这个世界上没有引力或任何东西。 (也许我应该使用角度和速度来获得我的精灵变量,但现在我正在使用speedX和speedY ......)

非常感谢!

5 个答案:

答案 0 :(得分:6)

将目标精灵视为二维房间中的直线,其中:

A(time) = (sprite.positionX + sprite.speedX * time, sprite.positionX + sprite.speedX * time)

由于你的子弹速度恒定,你也知道:

bullet.speedX^2 + bullet.speedY^2 = bullet.definedSpeed^2

然后你也可以计算子弹的直线:

B(time) = (bullet.positionX + bullet.speedX * time, bullet.positionX + bullet.speedX * time)

你知道这两条线都在某处:

A(time) = B(time)

然后由您决定使用您给定的值来解决这些方程式,并寻求time的最小值。

答案 1 :(得分:5)

答案 2 :(得分:3)

使用vectors可以使围绕这个的数学看起来更简单一些。 Sylvester似乎是JavaScript中有希望的向量实现,但出于我的例子的目的,我将编写自己的向量函数。我还假设.x / .y是在左上角测量的。

// this is a "constant"  - representing 10px motion per "time unit"
var bulletSpeed = 10; 
// calculate the vector from our center to their center
var enemyVec = vec_sub(targetSprite.getCenter(), originSprite.getCenter());
// measure the "distance" the bullet will travel
var dist = vec_mag(enemyVec);
// adjust for target position based on the amount of "time units" to travel "dist"
// and the targets speed vector
enemyVec = vec_add(enemyVec, vec_mul(targetSprite.getSpeed(), dist/bulletSpeed));
// calculate trajectory of bullet
var bulletTrajectory = vec_mul(vec_normal(enemyVec), bulletSpeed);
// assign values
bulletSprite.speedX = bulletTrajectory.x;  
bulletSprite.speedY = bulletTrajectory.y;  

// functions used in the above example:

// getCenter and getSpeed return "vectors"
sprite.prototype.getCenter = function() { 
  return {
    x: this.x+(this.width/2), 
    y: this.y+(this.height/2) 
  }; 
};

sprite.prototype.getSpeed = function() { 
  return {
    x: this.speedX, 
    y: this.speedY 
  }; 
};

function vec_mag(vec) { // get the magnitude of the vector
  return Math.sqrt( vec.x * vec.x + vec.y * vec.y); 
 }
function vec_sub(a,b) { // subtract two vectors
  return { x: a.x-b.x, y: a.y-b.y };
}
function vec_add(a,b) { // add two vectors
  return { x: a.x + b.x, y: a.y + b.y };
}
function vec_mul(a,c) { // multiply a vector by a scalar
  return { x: a.x * c, y: a.y * c };
}
function vec_div(a,c) { // divide == multiply by 1/c
  return vec_mul(a, 1.0/c);
}
function vec_normal(a) { // normalize vector
  return vec_div(a, vec_mag(a)); 
}

答案 3 :(得分:1)

计算射手和目标之间的距离:dist = sqrt((xt - xs)^2 + (yt - ys)^2)
将x和y距离除以上述距离:nx = (xt - xs)/dist; ny = (yt - ys)/dist;(向量的归一化)
将结果乘以一个因子,得到每个时间单位n个像素,即。每个方向的速度。它应该在想要的方向上保持恒定的速度。

答案 4 :(得分:0)

我假设目标将以恒定速度在直线上移动。

如果方向方向的子弹速度都是可变的(即您尝试计算子弹的speedXspeedY),则会有无数的解决方案。

如果设置固定方向,则只需将子弹和目标的两条线相交。从目标的当前点和交叉点(以及目标的速度)之间的距离,您可以计算目标到达此交叉点所需的时间。

从子弹的原点和交叉点(以及之前计算的时间)之间的距离,您可以计算子弹的速度。