我正在创建一个突破游戏,之前我在这里问过一个问题,但没有提出解决方案。我有一个简单的物理学来反演球与球拍碰撞时的Y
速度。但我要实现一个更先进的物理系统,例如,当球击中球拍的左侧和右侧时,等等……但我该如何计算碰撞后将球指向哪里?突破的标准是在碰撞时将球指向左侧,如果碰撞在右侧,则将球指向右侧,等等。
我如何计算在哪里击球?我有很多可以使用的变量,比如球拍的所有方面(宽度、高度、X
位置),球(半径、高度、宽度、X
和Y
速度、X
位置、Y
位置等),我通过使用鼠标监听器,从旧的X
位置减去新的X
鼠标位置,得到了球拍的运动,这样我就可以看到球拍移动的速度和方向。
这里有人熟悉基本物理,能够帮助我计算碰撞后的轨迹、路径、速度或方向吗?!
提前谢谢。
我们一直在为学校制作突围游戏。这就是我们的做法。注意,这是来自Ball类,所以每次看到这个都会想到Ball。
以下"反弹"方法计算并应用球的反弹会改变速度和旋转
"因素"表示如何在x和y方向转换为平行于表面的速度。如果我们调整我们的视野,使球朝着表面向下移动,如果移动到正确的
这些方程是根据以下物理分析得出的:Richard L.Garwin,"超弹性粗糙球的运动学",《美国物理学杂志》,3788-921969年1月。这决定了具有旋转的完全弹性球(弹性碰撞)的行为它在弹跳时不会打滑。真实世界的模拟是Wham-O的超级球产品。
我们进行了两次修改/专业化:1) 由于我们在二维空间中操作,所以我们的"球"是一个圆盘。这使转动惯量
1/2*M*R^2
在Garwin的论文,这意味着alpha=1/2。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,ω是自旋。)
/*
@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;
}
如果你不想学习高级物理,并且满足于台球般的行为,那么用你喜欢的方法计算碰撞点的表面法线(nx,ny)(标准化为nx²+ny²=1或nx=cos(a),ny=sin(a)),并像中那样改变方向
dot = nx*vx+ny*vy
vx = vx - 2*dot*nx
vy = vy - 2*dot*ny
这是一个几乎静止的桨。对于移动的桨叶,按照建议进行,首先从vx中减去桨叶速度pvx,计算点积和由此产生的变化,然后再加回桨叶速度。或者只在点积中进行减法,而不改变vx:
dot = nx*(vx-pvx)+ny*vy
vx = vx - 2*dot*nx
vy = vy - 2*dot*ny