在一个表面上弹球

4

我目前正在编写一个类似Breakout的游戏,我想知道如何正确地让球从表面弹开。

我采用了旋转速度90度的天真方法,具体如下:

[vx, vy] -> [-vy, vx]

很明显,这种方法并不奏效。如果我知道球的位置和速度,以及球将要撞上但实际上会反弹的点,那么我该如何让它反弹到那个点?

限制条件:

  • 我使用整数计算(无浮点数)
  • 所有表面都是简单的平面(垂直、水平或块状)
  • 我只想以90度角反弹
  • 所有碰撞都是纯弹性的(这是打砖块游戏——不需要摩擦等)

我不需要任何特定语言的代码。如果有人能提供一个小的、数学公式来正确地完成这个问题,那对我来说就足够了。

谢谢!


将速度旋转180°会变成[vx, vy] -> [-vx, -vy]。现在你正在旋转90°。 - kennytm
我的错误,我想写90度,而不是180度。 - Mike Bailey
1
为了进行一个合适的击球,你还需要将球棒的运动转移到球上。 - H H
7个回答

5
假设你只会在垂直或水平表面上弹跳,你可以分别将X或Y方向的速度取反。
所以,如果你有[vx,vy],它撞到了垂直墙壁,你会得到[-vx,vy]。
如果你有[vx,vy],它撞到了水平墙壁,你会得到[vx,-vy]。

我怎样才能知道这是一堵竖直的墙还是水平的墙呢? - apscience

5

我建议在水平墙上使用 [vx, vy] -> [vx, -vy],在竖直墙上使用 [vx, vy] -> [-vx, vy]。

注:[vx, vy] 表示速度向量的水平和垂直分量。

4

您需要在接触点处计算法向量。速度沿法线的分量会改变方向,而垂直于法线的速度分量将保持不变。

对于水平/垂直表面,法向量很容易计算。对于更复杂的表面,可能取决于表面的方程等。

此外,这假设球的能量不会改变。如果考虑摩擦/热损失/球的旋转等因素,情况可能会变得复杂。


1
谢谢。这解决了我的问题。我试图创建一个统一的反弹函数,可以在任何物体上使用,这样我就可以在任何表面(块、墙、挡板)的接触点上调用它。 - Mike Bailey

3

您正在围绕垂直于撞击点表面的一条线反射向量。在2D中:

出射角度 = 180度 - 撞击角度。


3
假设在碰撞过程中没有能量损失,一个速度为(vx, vy)的球在与垂直表面碰撞后会以(-vx, vy)的速度运动,在与水平表面碰撞后会以(vx, -vy)的速度运动。
对于一般情况(在任意法向量的平面上反弹,仍假设没有能量损失),请参见维基百科计算部分下的这篇文章:http://en.wikipedia.org/wiki/Specular_reflection

1
你需要知道球的表面和速度。例如,与x轴平行的线反弹时[vx, vy]会变成[vx,-vy]。如果该线与y轴平行,则[vx,vy]将变为[-vx,vy]。如果该线既不与x轴平行也不与y轴平行,则情况更加复杂,但您要寻找的是沿着表面方向的速度简单反射(对于x,y轴分别为(1,0)和(0,1))。

0

轴对齐框的90度反射只是适当地翻转X/Y速度符号的问题。此外,需要进行点积和一些向量调整,但这个数学仍然非常安全 - 如果需要,可以轻松地使用固定点完成。


虽然这是正确的,并且准确地回答了OP的问题,但这与OP实际想要的不符。想象一下一个球垂直于墙壁移动;你不希望那个球“弹起”并开始平行于墙壁移动。 - dash-tom-bang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接