纠正浮点舍入

时间:2014-05-17 04:54:38

标签: floating-point processing

我正在使用Processing进行杂耍游戏,并且在游戏中,多个球落下,然后通过点击它们将它们保持在空中。我的问题是,无论何时你点击球,它都会比以前更高。我想摆脱这个问题,但我不知道如何。我的导师说这是关于浮点数的问题。这是我到目前为止的代码。它创造了一个球,它向下加速,当它撞到墙壁时它会反弹回来。我的主要问题是,当你继续玩游戏时,球会消失。我该如何解决这个问题?

int lives = 3;
float xPos = (int)random(0,500);
float yPos = (int)random(25,50);
int col1 = (int)random(0,255);
int col2 = (int)random(0,255);
int col3 = (int)random(0,255);
int diameter = 50;
float xSpeed = (int)random(1,4)*random(-1,1);
float ySpeed = 0;
boolean xSwitch = false;
boolean ySwitch = false;

void setup()
{
  size(750, 750);
  while(xSpeed == 0)
  {
    xSpeed = (int)random(1,4)*random(-1,1);
  }
}

void draw()
{
  if(xSwitch)
  {
    xSpeed = -xSpeed;
  }
  xPos += xSpeed;
  if(ySwitch)
  {
    ySpeed = -ySpeed;
  }
  yPos += ySpeed;
  background(255, 255, 255);
  ellipse(xPos, yPos, diameter, diameter);
  fill(col1, col2, col3);
  ySpeed += 0.05;
  xSwitch = false;
  ySwitch = false;
  if(xPos-25 < 0)
  {
    xSwitch = true;
  }
  if(xPos+25 > 750)
  {
    xSwitch = true;
  }
}

void mousePressed()
{
  float diffX = mouseX - xPos;
  float diffY = mouseY - yPos;
  float hyp = sqrt(diffX * diffX + diffY * diffY);
  if(hyp < 25)
  ySwitch = true;
}

如果您需要澄清代码的任何部分,请在下面进行评论。

2 个答案:

答案 0 :(得分:1)

我以前遇到过这个问题。但我不知道为什么会发生这种情况。我决定从物理学角度而不是编码角度来解决这个问题,所以当然要做的第一件事就是看总能量(势能+动力学)。为此,我在绘图函数中包含了

println(0.5*(ySpeed*ySpeed + xSpeed*xSpeed) + g * (height-yPos));

这打印出加到势能(m * g * h)的动能(1/2 * m * v ^ 2)。这个总和应该是一个常数(数字本身是任意的),因为作用在球上的所有力都是保守的。请注意,m的值也是任意的,因此我将其保留为1。您会注意到,如果您将速度添加到位置,然后加速到速度,球将获得总能量:

23.61237
23.61362
23.614872
23.61612
23.61737
23.61862
23.619871

如果你反向执行动作(首先加速加速,然后加速到位置),球会失去总能量:

24.257536
24.256285
24.255035
24.253786
24.252535

有趣。好吧,如果以一种方式添加它会增加能量并以另一种方式添加它会减少能量,那么我们可以在这两种命令之间交替吗?

  if(frameCount % 2 == 0){
    yPos += ySpeed;
    ySpeed += g;
  } else {
    ySpeed += g;
    yPos += ySpeed;
  }

该方案(查看当前迭代#是偶数还是奇数)给出能量:

22.884935
22.886187
22.884935
22.886185
22.884935
22.886187
22.884935

不错。同样,我不确定为什么顺序很重要(它可能与辛与非辛数值积分有关,但我不是数值技术方面的专家),但你问过如何纠正它所以我认为这就足够了:))

旁注:您的代码中充满了750和25之类的“幻数”。如果您想要更改代码,则必须手动更改每一个代码 - 不仅单调乏味,而且你可能会错过一些。您已为这些值设置了变量:25为diameter/2,750为widthheight,因此请使用它们!它将使您的代码在未来的更改中更加健壮。

答案 1 :(得分:0)

由于您的问题是球离开屏幕,当球击中屏幕顶部并且即将更高时,请将y方向的速度设置为0.尝试将以下代码添加到您的绘图中()函数。

if(yPos - 25 > 0)
{
  ySpeed = 0;
}

这应该可以解决你的问题。