gpt4 book ai didi

2d 游戏 : fire at a moving target by predicting intersection of projectile and unit

转载 作者:行者123 更新时间:2023-12-03 02:26:03 25 4
gpt4 key购买 nike

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

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

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

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

最佳答案

我为 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 == 0t1t2 相等。

如果没有其他考虑因素,例如干扰障碍物,则只需选择较小的正值。 (负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)

关于2d 游戏 : fire at a moving target by predicting intersection of projectile and unit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2248876/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com