我们一直在为学校开发一款 Breakout 游戏。这就是我们的做法。请注意,这是来自 Ball 类,所以每次看到这个都认为Ball。
以下 Bounce 方法计算并应用球反弹的速度和旋转变化。
“因子”表示如何将 x 和 y 方向的速度转换为平行于表面的速度。如果我们调整我们的视角,使球朝表面向下移动,如果向右移动,平行于表面的速度是正的。
这些方程源自以下物理分析:Richard L. Garwin,“超弹性粗糙球的运动学”,美国物理学杂志,37,88-92,1969 年 1 月。这决定了完美弹力球(弹性球)的行为碰撞)与在弹跳时不滑动/滑动的旋转。真实世界的模拟是 Wham-O 的 Superball 产品。
我们做了两个修改/专业化:1)由于我们在二维中操作,我们的“球”是一个圆盘。这使得转动惯量
1/2 * M * R^2
. 在 Garwin 论文的约定中,这意味着 alpha = 1/2。Garwin 不考虑与移动表面的碰撞。但是,通过考虑相对于移动表面的框架的移动来调整事物是很容易的。在计算碰撞中发生的情况之前,我们只需从球的平行运动中减去表面的速度,然后再将速度加回来。
在 Garwin 的符号中,我们最终得到:
Ca = -1/3 Cb - 4/3 Vb + 4/3 Vs
Va = -2/3 Cb + 1/3 Vb + 2/3 Vs
这里 Va 和 Vb 分别是球在碰撞之后和之前平行于表面的速度。Vs 是表面的速度。Ca 和 Cb 分别是碰撞前后球的 R * 旋转。(在 Garwin 的表示法中,C = R * omega,其中 omega 是自旋。)
/*
@param xFactor an int, -1, 0, or 1, giving the factor by which to
multiply the horizontal speed to get its contribution to the speed
parallel to the surface
@param yFactor an int, -1, 0, or 1, giving the factor by which to
multiple the vertical speed to get its contribution to the speed
parallel to the surface
@param speed a double, giving the speed of the surface; positive
is movement to right if we consider the surface as being horizontal
with the Ball coming down onto it
*/
private void bounce (int xFactor, int yFactor, double speed) {
// can get stuck, so add a random component to the speed
speed += 0.03 * (random.nextFloat() - 0.5);
// obtain parallel / normal speeds for horizontal and vertical
double vParallel = xFactor * this.getHorizontalSpeed() +
yFactor * this.getVerticalSpeed();
double vNormal = xFactor * this.getVerticalSpeed() -
yFactor * this.getHorizontalSpeed();
double radius = this.getImage().getHeight() / 2.0D;
// determine Garwin's Cb and Vb
double cBefore = radius * spin;
double vBefore = vParallel;
// determine Garwin's Ca and Va
double cAfter = (-1.0D/3.0D) * cBefore + (-4.0D/3.0D) * vBefore + (4.0D/3.0D) * speed;
double vAfter = (-2.0D/3.0D) * cBefore + ( 1.0D/3.0D) * vBefore + (2.0D/3.0D) * speed;
// apply direction reversal to normal component
double vNAfter = -vNormal;
// determine horizontal and vertical speeds from parallel and normal components
double vHAfter = xFactor * vAfter - yFactor * vNAfter;
double vVAfter = xFactor * vNAfter + yFactor * vAfter;
// update the Ball's state
this.setHorizontalSpeed(vHAfter);
this.setVerticalSpeed(vVAfter);
this.spin = cAfter / radius;
}