2d 游戏:通过预测射弹和单位的交叉点向移动目标开火

2024-02-29

好吧,这一切都发生在一个美好而简单的 2D 世界中......:)

假设我有一个位于 Apos 位置的静态物体 A,一个位于 Bpos 且速度为 bVelocity 的线性移动物体 B,以及一个速度为 Avelocity 的弹药......

考虑到 B 的线速度和 A 弹药的速度,我如何找出 A 必须射击、击中 B 的角度?

现在目标是物体的当前位置,这意味着当我的射弹到达那里时,单位已经移动到更安全的位置:)


我写了一个瞄准子程序xtank http://quozl.netrek.org/xtank/一会儿回来。我将尝试阐述我是如何做到的。

免责声明:我可能在这里的任何地方犯了一个或多个愚蠢的错误;我只是想用我生锈的数学技能来重建推理。不过,我先切入正题,因为这是编程问答而不是数学课:-)

怎么做

它归结为求解以下形式的二次方程:

a * sqr(x) + b * x + c == 0

请注意,通过sqr我的意思是平方,而不是平方根。使用以下值:

a := sqr(target.velocityX) + sqr(target.velocityY) - sqr(projectile_speed)
b := 2 * (target.velocityX * (target.startX - cannon.X)
          + target.velocityY * (target.startY - cannon.Y))
c := sqr(target.startX - cannon.X) + sqr(target.startY - cannon.Y)

现在我们可以查看判别式来确定是否有可能的解决方案。

disc := sqr(b) - 4 * a * c

如果判别式小于 0,就别想击中目标了——你的射弹永远无法及时到达目标。否则,看看两个候选解决方案:

t1 := (-b + sqrt(disc)) / (2 * a)
t2 := (-b - sqrt(disc)) / (2 * a)

请注意,如果disc == 0 then t1 and t2是平等的。

如果没有其他考虑因素,例如介入障碍物,则只需选择较小的正值。 (消极的t值需要及时向后射击才能使用!)

替换所选的t将值带回到目标的位置方程中,以获得您应该瞄准的引导点的坐标:

aim.X := t * target.velocityX + target.startX
aim.Y := t * target.velocityY + target.startY

推导

在时间 T 时,弹丸与大炮的(欧几里德)距离必须等于经过的时间乘以弹丸速度。这给出了一个圆的方程,以经过的时间为参数。

sqr(projectile.X - cannon.X) + sqr(projectile.Y - cannon.Y)
  == sqr(t * projectile_speed)

类似地,在时间 T 处,目标沿其矢量移动时间乘以其速度:

target.X == t * target.velocityX + target.startX
target.Y == t * target.velocityY + target.startY

当炮弹与炮弹的距离匹配时,炮弹就能击中目标。

sqr(projectile.X - cannon.X) + sqr(projectile.Y - cannon.Y)
  == sqr(target.X - cannon.X) + sqr(target.Y - cannon.Y)

精彩的!将表达式替换为 target.X 和 target.Y 给出

sqr(projectile.X - cannon.X) + sqr(projectile.Y - cannon.Y)
  == sqr((t * target.velocityX + target.startX) - cannon.X)
   + sqr((t * target.velocityY + target.startY) - cannon.Y)

代入等式另一边可得:

sqr(t * projectile_speed)
  == sqr((t * target.velocityX + target.startX) - cannon.X)
   + sqr((t * target.velocityY + target.startY) - cannon.Y)

...减去sqr(t * projectile_speed)从两侧并翻转它:

sqr((t * target.velocityX) + (target.startX - cannon.X))
  + sqr((t * target.velocityY) + (target.startY - cannon.Y))
  - sqr(t * projectile_speed)
  == 0

...现在解析子表达式的平方结果...

sqr(target.velocityX) * sqr(t)
    + 2 * t * target.velocityX * (target.startX - cannon.X)
    + sqr(target.startX - cannon.X)
+ sqr(target.velocityY) * sqr(t)
    + 2 * t * target.velocityY * (target.startY - cannon.Y)
    + sqr(target.startY - cannon.Y)
- sqr(projectile_speed) * sqr(t)
  == 0

...并将相似的术语分组...

sqr(target.velocityX) * sqr(t)
    + sqr(target.velocityY) * sqr(t)
    - sqr(projectile_speed) * sqr(t)
+ 2 * t * target.velocityX * (target.startX - cannon.X)
    + 2 * t * target.velocityY * (target.startY - cannon.Y)
+ sqr(target.startX - cannon.X)
    + sqr(target.startY - cannon.Y)
  == 0

...然后将它们组合起来...

(sqr(target.velocityX) + sqr(target.velocityY) - sqr(projectile_speed)) * sqr(t)
  + 2 * (target.velocityX * (target.startX - cannon.X)
       + target.velocityY * (target.startY - cannon.Y)) * t
  + sqr(target.startX - cannon.X) + sqr(target.startY - cannon.Y)
  == 0

...给出标准二次方程t。找到该方程的正实零点给出(零、一或两个)可能的命​​中位置,这可以通过二次公式完成:

a * sqr(x) + b * x + c == 0
x == (-b ± sqrt(sqr(b) - 4 * a * c)) / (2 * a)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2d 游戏:通过预测射弹和单位的交叉点向移动目标开火 的相关文章

  • 计算圆交点 O( (n+s) log n)

    我试图弄清楚如何设计一种算法 可以以 O n s log n 复杂度完成此任务 s 是交叉点的数量 我尝试在互联网上搜索 但找不到真正的东西 无论如何 我意识到拥有良好的数据结构是关键 我在java中使用红黑树实现 TreeMap 我还使用
  • Java 2D 图像调整大小忽略双三次/双线性插值渲染提示(OS X + linux)

    我正在尝试使用 Image Voodoo 插件在 JRuby Rails 应用程序中为上传的图像创建缩略图 问题是调整大小的缩略图看起来像 屁股 似乎生成缩略图的代码绝对正确地执行了所有操作 将插值渲染提示设置为 双三次 但在我们的开发环境
  • d引用二维数组

    请看这段代码 include
  • 如何计算 2D 游戏中 SCREEN 到 WORLD 的位置

    我有这个类 我用它在我的 2D 游戏中绘制精灵 using Microsoft Xna Framework using Microsoft Xna Framework Graphics using Microsoft Xna Framewo
  • 更改Android自定义SurfaceView的大小

    我正在尝试为 Android 应用程序创建 2D 游戏引擎 我已经关注了本教程 http www droidnova com 2d tutorial series part ii 772 html 这对于创建全屏显示效果很好 但我不想要这样
  • 数学/算法/ JS:如何确定 2 个以上矩形是否相交,给定每个矩形的 TopLeft(x0, y0) 和 Bottom-Right(x1, y1)

    我遇到了完成我的申请所需的数学问题 所以我寻求帮助 给定 2 个 或更多 但基本上是 2 个 矩形 每个矩形有 2 个已知点 左上角 x1 y1 and 右下角 x2 y2 如果需要解决问题 我可以通过这些信息找到长度 TL x1 y1 T
  • Unity 2D Trail 渲染器碰撞

    我制作 2D unity 游戏 但我面临着我的游戏所依赖的一个主要问题 我将一个轨迹渲染器组件附加到我的播放器上 我需要的是使渲染器成为一个碰撞器 充当网格碰撞器我只是不知道是否可以使碰撞器呈现 2D 轨迹渲染器的形状 我在谷歌上搜索过 但
  • 计算 2D 向量叉积

    来自维基百科 叉积是a中两个向量的二元运算三维欧几里得空间产生另一个向量 该向量垂直于包含两个输入向量的平面 鉴于该定义仅定义为三个 或七 一和零 https en wikipedia org wiki Seven dimensional
  • 检查 C++ 中的映射是否包含另一个映射中的所有键

    我计划在 C 中使用两个类型的映射 std map
  • 查找椭圆或贝塞尔曲线上的等距点

    目前我正在编写 JavaScript 代码 将对象放置在屏幕上的椭圆上 我试图找到能够解决这个问题之一的算法 椭圆将是完美的 但如果它太昂贵 贝塞尔曲线也可以 抱歉 但不幸的是我的数学不允许我使用我找到的答案 https mathoverf
  • 如何用 Java 为 2D 游戏构建 Tiled 地图?

    不知道如何解决这个问题 基本上 我想要 400x400 窗口的 Pixel gt Tile 表示 屏幕上的每个坐标 例如120x300应该是图块的一部分 我最小的精灵是 4 个像素 所以我们可以说 1 个图块 4 个像素 玩家和敌人精灵都是
  • 2 个 SVG 路径的交集

    我需要检查两个 SVG Path 元素是否相交 检查边界框与 getBBox 太不准确了 我目前正在做的是迭代两条路径 getTotalLength 然后检查是否有两个点 getPointAtLength 是平等的 下面是一个片段 但正如您
  • 使用 LightGBM 进行多类分类

    我正在尝试使用 Python 中的 LightGBM 为多类分类问题 3 类 建模分类器 我使用了以下参数 params task train boosting type gbdt objective multiclass num clas
  • 如何从线性模型 (lm) 预测 x 值

    我有这个数据集 x lt c 0 40 80 120 160 200 y lt c 6 52 5 10 4 43 3 99 3 75 3 60 我使用计算了一个线性模型lm model lt lm y x 我想知道的预测值x如果我有新的y值
  • 适用于图形应用程序的快速、像素精度 2D 绘图 API?

    我想创建一个跨平台的绘图程序 编写应用程序的一个要求是画布上具有像素级精度 例如 我想编写自己的画线算法 而不是依赖别人的 我不想要任何形式的抗锯齿 同样 需要像素级控制 我希望屏幕上的用户交互快速且响应灵敏 取决于我编写快速算法的能力 理
  • 从两个相交的多边形创建新的 MKPolygon

    我知道确实有一个具体的问题讨论了这一点 但它有点老了 如果可能的话 我想了解更多技术性的知识 首先看一下这个截图 https www dropbox com s f94q3qaxrog0ec9 intersections png https
  • 从多个地方绘制 JPanel

    我目前正在为学校开发一款 Java 2D 游戏 我们必须使用抽象工厂设计模式 对于 2D 实现 我使用工厂如下 public class Java2DFact extends AbstractFactory public Display d
  • Java Swing 自定义形状(2D 图形)

    我需要绘制自定义形状 现在 当用户单击面板上的几个点时 我使用多边形创建一个形状 public void mouseClicked MouseEvent e polygon addPoint e getX e getY repaint 但我
  • 如何光栅化旋转矩形(通过 setpixel 在 2d 中)

    我有四个 2d 顶点 A B C D 的旋转矩形 我需要在像素缓冲区中 有效地 光栅化 绘制它 使用 setpixel x y 颜色 怎么做 我正在尝试使用一些代码 例如 convertilg a b c d do up down left
  • 如何使用现有列表创建二维数组?

    例如 我有一个名为 mazeline 的 txt 数据 如下所示 abcd cdae korp 所以我首先列出了 3 个清单 mazeline readmaze split mline0 list mazeline 0 mline1 lis

随机推荐