首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >2D游戏算法来计算子弹命中目标所需的速度?

2D游戏算法来计算子弹命中目标所需的速度?
EN

Stack Overflow用户
提问于 2010-07-09 17:26:34
回答 4查看 4.4K关注 0票数 9

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

我正在使用JavaScript,并拥有这些sprite变量(以及其他变量):sprite.x、sprite.y、sprite.width、sprite.height、sprite.speedX (即速度)、sprite.speedY……因此,我有对象originSprite、targetSprite和bulletSprite,它们都具有这些类型的值,并且我需要设置正确的bulletSprite速度值。

可能为了让它看起来更漂亮,子弹会从originSprite的外部开始(或者某个定义的半径,尽管我猜从originSprite中心开始也可以),但它的子弹中心会尝试击中targetSprite的中心。请注意,在这个世界上没有重力或任何东西。(也许我应该让我的sprites变量使用角度和速度,但现在我使用的是speedX和speedY...)

非常感谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-07-09 18:32:13

使用vectors可以使这方面的计算看起来更简单一些。在JavaScript中,Sylvester似乎是一个很有前途的向量实现,但出于示例的目的,我将编写自己的向量函数。我还将假设.x / .y是在左上角测量的。

代码语言:javascript
运行
复制
// 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
EN

Stack Overflow用户

发布于 2010-07-09 17:44:48

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

代码语言:javascript
运行
复制
A(time) = (sprite.positionX + sprite.speedX * time, sprite.positionX + sprite.speedX * time)

因为你的子弹有恒定的速度,你也知道:

代码语言:javascript
运行
复制
bullet.speedX^2 + bullet.speedY^2 = bullet.definedSpeed^2

然后,您还可以为项目符号计算一条直线:

代码语言:javascript
运行
复制
B(time) = (bullet.positionX + bullet.speedX * time, bullet.positionX + bullet.speedX * time)

你知道这两条线在某处交错:

代码语言:javascript
运行
复制
A(time) = B(time)

然后由你用你给出的值来求解这些方程,并寻找time的最小值。

票数 6
EN

Stack Overflow用户

发布于 2010-07-09 17:40:36

计算射手和目标之间的距离:dist = sqrt((xt - xs)^2 + (yt - ys)^2)

将x和y距离除以上面的值:nx = (xt - xs)/dist; ny = (yt - ys)/dist; (向量的标准化)

将结果乘以一个因子,得到每个时间单位的n个像素,即。每个方向的速度。它应该在想要的方向上提供恒定的速度。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3211374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档