【问题标题】:Java Tower Defense Missile CalculationJava塔防导弹计算
【发布时间】:2012-07-29 21:01:51
【问题描述】:

我正在尝试开发一个小型 Java 2d 塔防游戏,但在尝试计算如何制造导弹时遇到了问题。经过数小时的搜索和测试,我更加困惑。

到目前为止我所拥有的是:

  1. 4 种情况,具体取决于炮塔所在的位置,具体取决于炮塔所在的单位(西北、东北、西南、东南)
  2. 我需要使用Math.sqrt(x2, x1, y2, y1) 计算当前目标与导弹发射塔之间的距离。
  3. 缩放导弹的 x 和 y。

现在我遇到的问题是如何将导弹的增量 x 和 y 缩放到目标,这样看起来很现实。数学不是我的强项,它在这里展示。下面我展示了我在塔的 SE 象限中拥有的东西。

public int distanceX, distanceY;
public double sep, scale;

if(xBullet < Screen.mobs[shotMob].x && yBullet < Screen.mobs[shotMob].y){
        distanceX = Screen.mobs[shotMob].x- xBullet;
        distanceY = Screen.mobs[shotMob].y - yBullet;
        sep = Math.sqrt( (distanceX * distanceX) + (distanceY * distanceY));
        scale = // This is the part I am confused about.
        xBullet += distanceX * scale;
        yBullet += distanceY * scale;

【问题讨论】:

  • 您应该考虑使用/编写一个 Vector2D 类来简化向量计算。在游戏开发中你会非常需要它们。实现这样一个类应该很容易。
  • “数学不是我的强项” 看来编写自己的游戏物理可能有点问题。为什么不使用现有的游戏框架?
  • @cjr,你最后是怎么解决你的问题的?
  • 这是几年前的事了,项目最终失败了,没有代码/记住我为解决问题所做的工作:D

标签: java math 2d game-physics


【解决方案1】:

如果你想要一个固定的速度,只需使用:

scale = someConstant;

要移动子弹,你可以使用你已经找到的方向向量,但你必须通过除以距离来归一化它:

xBullet += (distanceX / sep) * scale;
yBullet += (distanceY / sep) * scale; 

基本上你会得到你想要去的方向的速度单位向量,然后你将它与速度相乘以获得实际的速度向量。不过,您的 xBulletyBullet 字段应该是浮点值(例如双精度),而不是整数。

【讨论】:

  • 整数是没有错的:)只要够大就行。
  • 如果子弹在接近水平/垂直的任何地方移动,那么你会发现使用整数会出现问题。
【解决方案2】:

我不确定你的意思..道歉。无论如何,你不能做类似的事情..

xMissile += (xTarget-xOrigin)/numberOfSteps
yMissile += (yTarget-yOrigin)/numberOfSteps

这只是在给定步数内通过路段到达目的地的一种简单方法

【讨论】:

    【解决方案3】:

    我今天要做一个塔防。我已经考虑过了,这就是我从塔楼等处射击的方式。

    如何计算到目标的距离: 勾股定理。 x 目标 - x 塔用于它的一个长度,y 目标 - y 塔用于它的其他长度。将它们都平方,然后将它们加在一起,然后平方根您得到的数字。这就是目标的距离。虽然它需要一些其他代码才能正常工作(您可能会得到负值的长度,所以您需要再次更改为正值)

    条件:如果到目标的距离小于塔的攻击范围: 动作:塔射击 response : 创建一个固定目标的子弹

    循环:比较目标和导弹之间的 x 和 y 并相应地增加 x 或 y。

    action : 导弹 x 和 y 与目标 x 和 y 相同 response : 对目标造成伤害并移除导弹

    【讨论】:

      【解决方案4】:

      您将需要单独的 x 比例和 y 比例。 x 比例应该是从枪到目标的水平距离除以它击中之前的动画总帧数,y 比例应该相同但垂直距离

      【讨论】:

      • 所以之前的总帧数可能是我计算的距离,给我类似 xscale = (xbullet - xmob)/distance ?
      • 我相信是的。您甚至可以通过将其更改为 xscale = (xbullet - xmob)/(distance * speed); 来添加可变速度;
      • +1 parametric form of a parabola 非常适合这里。
      【解决方案5】:

      现在我遇到的问题是如何将导弹的增量 x 和 y 缩放到目标,这样看起来很现实。

      这需要有多现实?

      我不是导弹专家,但我猜想一旦发射简单的导弹可以近似通过固定的方向和速度。然后他们会继续朝那个方向前进,直到他们撞到什么东西、燃料用完或重力把他们拉下来。当导弹发射时,您可以存储它的方向和速度,并在每一步移动导弹适当的恒定距离(您可以使用trigonometric formulae 转换为 x 和 y 坐标)。

      double delta_distance = speed * delta_time;
      double delta_x = Math.cos(angle) * delta_distance;
      double delta_y = Math.sin(angle) * delta_distance;
      

      正如 cmets 中所指出的,您可以选择使用速度矢量,而不是单独存储角度和速度。

      小提示:恒定速度只是一个近似值,有几个原因。当导弹第一次发射时,它必须加速,直到推进力等于空气阻力的阻力。此外,随着燃料的燃烧,它们实际上可能能够更快地行驶,因为它们具有相同的力但质量更小。但是对于塔防游戏来说,这种细节水平并不是必需的。恒定速度是合理的简化。

      如果您的目标可能快速移动并改变方向,我认为该算法不适用于您,因为导弹经常会错过目标。

      更先进的热追踪导弹将能够锁定目标并跟踪它。他们需要能够在目标移动时改变方向,但我猜他们可能不会调整速度。由于物理限制,它们改变方向的速度也会受到限制,因此您可能也想对其进行建模。否则,您可能会让导弹飞过目标,然后突然翻转并立即朝相反方向飞行,而无需先减速或转弯 - 这不太现实。

      复杂的导弹可能会尝试根据其当前速度预测其目标移动到的位置。他们将计算出一条路径,使目标的当前轨迹与计算出的导弹轨迹相撞。如果目标的移动发生变化,则必须更新此计算。显然这有点难以实现,但请记住,您的玩家想要玩爆破怪物。如果所有的导弹都没有击中目标,他们将不会有太多乐趣。因此,在确保您的导弹现实有效方面进行一些额外的工作将使您的游戏变得更好。

      【讨论】:

      • 好吧,我的第一次尝试甚至没有使用距离公式,而是简单地将 x 和 y 增加 1 直到达到目标,但当然会发生什么值在另一个值之前达到看起来块状。我没有想过要制造这样的导弹来瞄准它所在的位置,这听起来很神奇,但对于我的编程知识水平来说可能超出了我的想象。
      • 只使用方向向量即可,既简单又快捷。
      • 使用向量并不是过早的优化;它们非常自然地表达了速度等概念。我认为使用角度进行旋转实际上是一种过早优化的情况,因为他没有提到需要。
      • @Zongli:谢谢你对 cme​​ts 的解释。我希望 OP 可以看到这两种方法在简单的情况下给出了相同的结果。对于更复杂的情况,显然他需要使用角度来保持真实感,所以我在回答中保持角度以保持一致。这也意味着他可以从简单开始,尽可能容易地从简单过渡到逐渐复杂,而不需要他完全重写所有内容。
      • 好吧,我想我们应该结束这个冗长的讨论了。 :) 我同意角度是有用的,但向量是表示这些类型数量的标准方式(在编程和物理学中)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      • 1970-01-01
      相关资源
      最近更新 更多