需要帮助找出我的游戏的2D轨道

时间:2019-02-02 18:13:38

标签: vector processing game-physics game-development

在我正在制作的游戏中,其想法是鼠标光标代表重心,并且周围有物体在旋转。 游标本身不是对象,并且游标和对象之间没有冲突。

一种理想的方法是我可以输入目标的 x y 坐标,也许可以输入轨道半径,然后物体进入轨道并会不断加速。
当我移动鼠标时,对象将跟随;当我停止它时,它会回到相同的轨道半径。
对象的加速度还应该能够改变,从而使鼠标具有更多或更少的质量。

我认为实现此目标的最佳方法可能是使用向量。

在“弹丸”类中,我给每个弹丸4个字段:x坐标,y坐标,PVector速度和PVector acc(加速度)。

我尝试的第一件事是使对象保持恒定的加速度。速度矢量从零开始,计算加速度矢量,然后将其大小设置为某个值,并将其添加到速度矢量中。 这产生了很大的轨道,加速缓慢,并且当鼠标移动时,轨道就变大了。

接下来,我尝试在接近实际行星启发的质心时使加速度增加。这也不起作用。轨道仍然太大,无法控制。有点令人失望,我试图使加速度不断提高,从而获得最佳效果。现在,轨道变小了,但是它一直在减小到一定半径,然后停止。如果它停止减小的半径是可配置的,那么这将是完美的,但是无论参数如何,轨道总是太大,并且轨道大小持续缓慢地缓慢减小。我的猜测是,加速度和速度最终会达到平衡,然后轨道停止减小。

void move(float x,float y,float accm)
  {
    PVector target = new PVector(x, y);
    PVector ball = new PVector(this.x, this.y);
    acc = PVector.sub(target, ball);
    acc.setMag(accm);
    speed.add(acc);
    println(acc.mag() + " " + speed.mag());
    this.x = this.x + speed.x;
    this.y = this.y + speed.y;
  }

这是提供最佳结果的功能。该函数在draw()中调用:

if(mousePressed == true)
  {
    for(i=0;i<nproj;i++)
    {
      a[i].move(mouseX, mouseY,k);
    }
    k += n;
  }

k是赋予函数的数字,n是加速度增加的速率。我尝试了许多不同的加速度大小和不同的加速度,但无法弄清楚。 Nproj是弹丸的数量,a是弹丸阵列的名称。

我发现,对于k = 0和n = 0.002,它给出了最可靠和稳定的结果。如果n较大(大约0.01或更大),则对象有时会随机飞出比预期更远的距离,并且实际上会增加轨道半径。随着加速度的增加,这种情况会更频繁地发生,并且对象有时会离开屏幕,然后再也不会回来。我知道轨道半径不存在是因为轨道是椭圆形的,但这只是使其易于解释。

更新: 到目前为止,这是我想出的

void move(float x,float y,float accm)
  {
    PVector target = new PVector(x, y);
    PVector ball = new PVector(this.x, this.y);
    acc = PVector.sub(target, ball);
    acc.setMag(accm);
    vel.add(acc);
    this.x = this.x + vel.x;
    this.y = this.y + vel.y;
    vel.limit(15);
  }

draw()

if(mousePressed == true)
  {
    for(i=0;i<nproj;i++)
    {
      a[i].move(mouseX, mouseY,k);
    }
    k += n;
    if(k > 25)
    n = 0;
  }

通过限制速度矢量并不断增加加速度矢量,幅度差开始增加,并且由于加速度矢量不断增加且速度矢量恒定且加速度矢量指向目标,因此矢量的总和开始越来越缓慢地指向朝目标前进。条件if(k < 25)可以限制加速度,并且可以通过更改加速度的限制来更改轨道半径。

1 个答案:

答案 0 :(得分:1)

我认为您可能会在https://physics.stackexchange.com/上获得更快的答案,并将您的问题归纳为“我如何在游戏中模拟重力?”

无论如何,我会尝试一下...

  

在“弹丸”类中,我给每个弹丸4个字段:x坐标,y坐标PVector速度和PVector acc

到目前为止,声音还不错,只是不需要将加速度矢量与对象一起存储。您将在模拟的每个“刻度”上为每个对象计算一个新的加速度矢量。

我将在此处使用标准物理学术语,并将每个对象的向量称为velocity而不是speed

  

接下来,我尝试在接近实际行星启发的质心时使加速度增加。

如果您使用正确的算法来计算轨道,这种行为自然就会发生。

您的“太阳”和“行星”各有一个质量。质量是由WikipediaF = G * m1 * m2 / d^2引力相互吸引的。

请记住Force = mass * acceleration,加速度为a = m * G / d^2,其中m是另一个物体(在这种情况下为太阳)的质量,而d是两个物体之间的距离。因此重要的一点是,物体在重力作用下的加速度随两个物体之间的距离距离平方而变化。

因此,用于模拟单笔交易的基本算法如下:

  • 对于每个行星,计算加速度矢量
  • 使用到“太阳”的距离平方作为加速度矢量的大小(乘以取决于“重力常数”和太阳质量的常数值),方向为沿着从行星到太阳的方向
  • 将此加速度矢量添加到行星的速度矢量
  • 将速度矢量添加到行星的(x,y)位置以使其向前移动。

对于每个模拟刻度的长度,重力常数和太阳的质量都有适当的值,这应该看起来很合理。

由于您假设行星都是独立的并且不会碰撞,因此您可以为每个行星独立地进行计算。

但是,我认为通过更精确的模拟游戏可能会更有趣。实际上,每个物体在每个其他物体上都具有重力。这将意味着遍历所有对象对,并执行相同类型的加速度/速度/位置计算。

然后,游戏的重点可能是使“行星”从屏幕的一侧移到另一侧,这是一种越来越困难的起始配置,因为它们相互影响并且朝着不同的方向移动。

为了使所有这些工作顺利进行,重要的是将“太阳”的质量设置为比行星质量高很多倍,并根据时间为重力常数选择一个合理的值您的模拟。您必须使用这些常数才能找到最佳结果。