让球反弹停止

时间:2015-05-27 16:38:34

标签: java physics bounce

我有一个带有以下变量的球类:

int x,y,width,height;
double velX,velY;

我想这样做,以便每当球击中一个阻挡时,它会反弹并且会失去一些速度。

//Gravity & movement for the ball
ball.setVelY(ball.getVelY() + 0.2);

ball.setY((int)(ball.getY() + ball.getVelY()));

//Make the ball bounce.
if(ball.getBounds().intersects(block.getBounds()){
     ball.setVelY(ball.getVelY() * -0.7);          
}

我认为这会使球慢慢反弹,直到它完全移动大麦(我会测试然后让球完全停止),但事实并非如此。球会正常弹跳几次,每次弹跳都小于之前的弹跳。然而,在几次反弹之后,球将比之前的反弹更低地弹跳。为什么这个以及我该怎么做才能解决它?

2 个答案:

答案 0 :(得分:7)

这里的问题是你基本上是对球施加小的力量。即使你正在缩小势头,你也会不断将0.2的这个值加到球的动量上。

作为一个类比,你通过定期施加重力来做的是在短时间内向下击球,给它带来动力。如果您想象一个仍然在地面上或稍高于地面的篮球,并且您开始快速点击它,则可以使球反弹。但是,如果你想象用手向球施加恒定的向下力(就像重力一样),那么球将无法反弹。

由于不可能让你的程序以连续的方式运行,可以这么说,你必须找到解决这个问题的方法。一种解决方案是在与地板撞击时简单地检查动量的最小阈值,如果它低于该阈值,则将其动量设置为0,并将其设置为使其与表面相连。

答案 1 :(得分:1)

问题可能是数字问题。写作时你在做什么

ball.setVelY(ball.getVelY() + 0.2);
ball.setY(ball.getY() + ball.getVelY());

使用Euler method积分微分方程。事实上,它是简化:

ball.setVelY(ball.getVelY() + g * DeltaTime); // g = 9.8m/s² for earth gravity
ball.setY(ball.getY() + ball.getVelY() * DeltaTime);

其中DeltaTime是您的集成时间步骤,为简单起见,您将其等于一。

不幸的是,Euler方法只是条件稳定,这意味着你可以在速度发散的情况下结束(或者这种类型的永无止境的振荡)。为了恢复稳定性,最好的方法是减少时间步长,在你的情况下意味着降低速度,或者说减少重力。尝试将 g 从0.2设置为0.05,并将计时器的频率提高4以验证这一点。

如果你是数学,你也可以看看无条件稳定的方法,例如backward Euler method