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 游戏:通过预测射弹和单位的交叉点向移动目标开火 的相关文章

  • 在 Win32 C++ 中创建 GUI

    我正在开发我的第一个 Windows 桌面应用程序 并且正在尝试找出创建该程序的 GUI 的最佳方法 我知道 我知道 考虑到有关该主题的数据量 我觉得问这个问题很愚蠢 然而 大多数答案似乎已经过时 我不确定它们是否适合我的特定项目 另外 W
  • 检测数组中作为复杂多边形顶点的一组点是否按顺时针或逆时针顺序定义?

    编辑 我更新了program http colekito com ProgrammingProjects Science 20Fair 有了答案 效果很好 我正在做一个program http colekito com Programmin
  • 让背景或相机根据角色位置“滚动”

    我正在开发一款具有自上而下视图的角色扮演游戏 我想将一张图片加载到角色正在行走的背景中 但到目前为止我还没有弄清楚如何正确地重绘背景以使其 滚动 我发现的大多数示例都是自动滚动的 我希望相机保持在角色中心 直到背景图像到达其边界 然后角色将
  • 范围交集/并集

    我正在开发一种编程语言 我想为其提供Range数据类型 目前不像通常那样是一个成对的列表int values x y 的约束条件是x lt y 我说不像通常那样 因为通常范围只是一对 但在我的情况下 它超过 例如允许 1 to 5 7 to
  • 预测多个单独组的线性回归

    我想预测单个数据框中多个组的线性回归的值 我发现以下博客文章几乎可以满足我需要的一切 https www r bloggers com 2016 09 running a model on separate groups https www
  • 我应该如何在这个 2d Java 游戏中实现跳跃/重力/下落

    所以这是我的Player类 我想在空格键上跳转的对象 我只是不知道从哪里开始 我可以在互联网上阅读与我相关的任何好的资源吗 任何帮助都很棒 谢谢 package com zetcode import java awt Color impor
  • 获取GeneralPath的有序顶点

    如何获取 GeneralPath 对象的顶点 看起来这应该是可能的 因为路径是由点 lineTo curveTo 等 构造的 我正在尝试创建点数据的 double x y 坐标数组 您可以从以下网站取回积分PathIterator http
  • 更改Android自定义SurfaceView的大小

    我正在尝试为 Android 应用程序创建 2D 游戏引擎 我已经关注了本教程 http www droidnova com 2d tutorial series part ii 772 html 这对于创建全屏显示效果很好 但我不想要这样
  • 操作系统如何在屏幕上绘制窗口?

    经过多年的计算机使用和编程 我意识到实际在屏幕上绘制的软件堆栈对我来说基本上是一个谜 我曾研究过一些嵌入式 LCD GUI 应用程序 我认为这为简化堆栈提供了一些线索 但对于 Windows 操作系统之类的东西的整体情况仍然模糊 据我所知
  • 张量流将预测作为 b64 输出顶部结果

    我有一个 Keras 模型 我将其转换为张量流服务模型 我可以成功地将预训练的 keras 模型转换为采用 b64 输入 预处理该输入并将其提供给我的模型 我的问题是我不知道如何获取我得到的预测数据 这是巨大的 并且只导出最高结果 我正在进
  • 计算 2D 向量叉积

    来自维基百科 叉积是a中两个向量的二元运算三维欧几里得空间产生另一个向量 该向量垂直于包含两个输入向量的平面 鉴于该定义仅定义为三个 或七 一和零 https en wikipedia org wiki Seven dimensional
  • 如何使用 Unity 将基于 2D 数组的图块实例化到平台游戏中?

    我正在构建一个非常简单的平台游戏 使用 2D 数组来构建基于它的地图 我想要两个简单的目标 但目前还没有找到答案 确保相机为 16 9 并且我的场景将 100 显示在其中 像在数组中一样构建 2D 平台图块集 我的环境 Unity 5 5
  • 在matlab中绘制颜色编码图

    我需要使用 dat 文件绘制颜色编码的二维图 文件中的数据排列为 48 000000 0 000184 0 400000 48 500000 0 000185 0 400000 49 000000 0 000186 0 400000 49
  • Java - 二维数组检查对角线数字板

    目前我正在开发一个在 8x8 2D 阵列板中生成随机 0 和 1 的程序 我要做的是检查对角线上的所有数字是否相同 从角开始 而不仅仅是任何对角线 example int array 0 0 0 0 0 0 0 1 0 0 1 0 1 0
  • 具有混合成员类型的通用 TypeScript 接口

    对于几个 HTML 表单 我想配置输入并处理它们的值 我的类型具有以下结构 您可以将其复制到 TypeScript Playgroundhttp www typescriptlang org play http www typescript
  • 如何在几年前拟合的逻辑回归中使用 R 中的预测函数?

    我有一个问题正在尝试解决 但没有成功 寻找了两天多 却没有得到任何线索 很抱歉 如果答案就在那里 但我没有找到 假设您有一个来自几年前估计的旧模型的逻辑方程回归 二元模型 因此 您知道参数 k k 1 2 p 因为它们是过去估计的 但您没有
  • 标准化设备坐标

    我正在编写一个处理 2D 图形形状的库 I m just wondering why should my coordinate system range from 1 1 for both the x and y axis instead
  • Python lmfit:拟合 2D 模型

    我正在尝试将二维高斯拟合到一些灰度图像数据 该数据由一个二维数组给出 lmfit 库实现了一个易于使用的模型类 它应该能够做到这一点 不幸的是文档 http lmfit github io lmfit py model html http
  • 二维几何:如何检查点是否在角度内

    我有以下二维几何问题 我有一个点 从该点投射一个无限角度 2D 锥体 该角度由方向和角度给出 该点和方向形成一个向量 并且角度的每一侧一半形成 2D 锥体 现在我想检查 2D 中的另一个点是在这个圆锥体内部还是外部 如何才能实现这一目标 谢
  • 2 个 SVG 路径的交集

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

随机推荐