【问题标题】:Make ball bounce to a stop使球弹起停止
【发布时间】:2015-05-28 01:13:15
【问题描述】:

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

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);          
}

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

【问题讨论】:

    标签: java physics bounce


    【解决方案1】:

    这里的问题是,您实际上是在离散地对球施加小的爆发力。即使您正在缩小动量,您也会不断地将0.2 的值添加到小球的动量中。

    打个比方,通过周期性地施加重力,您正在做的就是在短时间内将球向下敲击,使其具有动量。如果您想象一个静止的篮球球在地面上或稍稍高于地面,然后您开始快速敲击它,则有可能使球反弹。但是,如果您想象用手对球施加恒定的向下力(就像重力一样),那么球将无法反弹。

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

    【讨论】:

    • 我同意这个评估。最好以连续的方式施加力,然后检查阈值(例如 0 或更小)。通过这种方式,您可以避免它必须定期更新,并且让它不断运动,直到其他力量/等影响它。
    【解决方案2】:

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

    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 是您的积分时间步长,为简单起见,您取其等于一。

    不幸的是,欧拉方法只是条件稳定,这意味着您最终可能会遇到速度发散的情况(或这种永无止境的振荡)。为了恢复稳定性,最好的方法是减少时间步长,这在您的情况下意味着降低速度,或者更确切地说是降低重力。尝试将 g 从 0.2 设置为 0.05,并将计时器的频率增加 4 以验证这一点。

    如果您对数学感兴趣,还可以查看无条件稳定方法,例如 backward Euler method

    【讨论】:

      猜你喜欢
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      • 2017-07-20
      • 1970-01-01
      • 2012-06-18
      • 2011-02-20
      相关资源
      最近更新 更多