Python 简单的弹跳物理
Python simple bouncing physics
我想知道是否有一种直接的方法可以在 Python 中实现弹跳物理,而无需任何物理模块。我所说的弹跳物理,不是指重力,我的意思更像是 Philipp Stollenmayer (https://appsto.re/us/1N7v5.i) 最近发布的 iOS 游戏 "Okay?"。我知道如果一个球碰到直边,它的速度就会倒转。因此,鉴于此图:
当球击中 A 和 C 时,它的 X 速度反转,当它击中 B 和 D 时,它的 Y 速度反转。但是,如果我们的图表看起来像这样怎么办:
给定平台的角度,如何找到新的 X 和 Y 速度?另外,如何将这些 X 和 Y 速度转换为度数?
我从维基百科了解到,反弹的对称线垂直于它撞击的表面。
我的最后一个问题是如何在 pygame 中找到一条线的角度,并创建一条具有特定角度的线。
reflectedVector = velocityVector - scale(surfaceNormal, 2.0*dot(surfaceNormal, velocityVector))
velocityVector
为移动速度,用Vector表示,向表面移动。
surfaceNormal
垂直于面,长度为1。
dot
是 dot product。 dot(v1, v2) = v1.x*v2.x + v1.y*v2.y
scale
是向量"scale"运算。 scale(inVec, scalar) = vector2d(inVec.x*scalar, inVec.y*scalar)
`
仅当它指向表面时才反射速度,如果它正在远离,则不要。
- 如果
dot(surfaceNormal, velocity) < 0
球正朝它移动。
- 如果
dot(surfaceNormal, velocity) == 0.0
球与表面平行。
- 如果
dot(surfaceNormal, velocity) > 0.0
球正在远离表面。
这里有一些简单的技巧,变得容易理解。为此,我使用了 pygame。我们需要一些常量,如 'frame rate' 和像素位移 [ball] 来可视化结果。我们做的就是这个。一旦它撞到墙壁,我们就会根据墙壁的哪一侧改变像素的流动方向。 [对我们来说它看起来像是从墙上偏转]
关注代码。
self.ball = pygame.Rect(300,PADDLE_Y - BALL_DIAMETER,BALL_DIAMETER,BALL_DIAMETER)
self.ball_vel = [10,-10]
self.ball.left += self.ball_vel[0]
self.ball.top += self.ball_vel[1]
if self.ball.left <= 0: #---1
self.ball.left = 0
self.ball_vel[0] = -self.ball_vel[0]
elif self.ball.left >= MAX_BALL_X: #---2
self.ball.left = MAX_BALL_X
self.ball_vel[0] = -self.ball_vel[0]
if self.ball.top < 0: #---3
self.ball.top = 0
self.ball_vel[1] = -self.ball_vel[1]
elif self.ball.top >= MAX_BALL_Y: #--4
self.ball.top = MAX_BALL_Y
self.ball_vel[1] = -self.ball_vel[1]
# If the ball hits the left wall it has to invert its velocity [Moving left become right] ---1
# If the ball hits the Right wall it has to invert its velocity [Moving right become left] ---2
# If the ball hits the Bottom wall it has to invert its velocity [Moving downwards become upwards] ---3
# If the ball hits the Right wall it has to invert its velocity [Moving upwards become downwards] ---4
我想知道是否有一种直接的方法可以在 Python 中实现弹跳物理,而无需任何物理模块。我所说的弹跳物理,不是指重力,我的意思更像是 Philipp Stollenmayer (https://appsto.re/us/1N7v5.i) 最近发布的 iOS 游戏 "Okay?"。我知道如果一个球碰到直边,它的速度就会倒转。因此,鉴于此图:
我从维基百科了解到,反弹的对称线垂直于它撞击的表面。
我的最后一个问题是如何在 pygame 中找到一条线的角度,并创建一条具有特定角度的线。
reflectedVector = velocityVector - scale(surfaceNormal, 2.0*dot(surfaceNormal, velocityVector))
velocityVector
为移动速度,用Vector表示,向表面移动。
surfaceNormal
垂直于面,长度为1。
dot
是 dot product。 dot(v1, v2) = v1.x*v2.x + v1.y*v2.y
scale
是向量"scale"运算。 scale(inVec, scalar) = vector2d(inVec.x*scalar, inVec.y*scalar)
`
仅当它指向表面时才反射速度,如果它正在远离,则不要。
- 如果
dot(surfaceNormal, velocity) < 0
球正朝它移动。 - 如果
dot(surfaceNormal, velocity) == 0.0
球与表面平行。 - 如果
dot(surfaceNormal, velocity) > 0.0
球正在远离表面。
这里有一些简单的技巧,变得容易理解。为此,我使用了 pygame。我们需要一些常量,如 'frame rate' 和像素位移 [ball] 来可视化结果。我们做的就是这个。一旦它撞到墙壁,我们就会根据墙壁的哪一侧改变像素的流动方向。 [对我们来说它看起来像是从墙上偏转] 关注代码。
self.ball = pygame.Rect(300,PADDLE_Y - BALL_DIAMETER,BALL_DIAMETER,BALL_DIAMETER)
self.ball_vel = [10,-10]
self.ball.left += self.ball_vel[0]
self.ball.top += self.ball_vel[1]
if self.ball.left <= 0: #---1
self.ball.left = 0
self.ball_vel[0] = -self.ball_vel[0]
elif self.ball.left >= MAX_BALL_X: #---2
self.ball.left = MAX_BALL_X
self.ball_vel[0] = -self.ball_vel[0]
if self.ball.top < 0: #---3
self.ball.top = 0
self.ball_vel[1] = -self.ball_vel[1]
elif self.ball.top >= MAX_BALL_Y: #--4
self.ball.top = MAX_BALL_Y
self.ball_vel[1] = -self.ball_vel[1]
# If the ball hits the left wall it has to invert its velocity [Moving left become right] ---1
# If the ball hits the Right wall it has to invert its velocity [Moving right become left] ---2
# If the ball hits the Bottom wall it has to invert its velocity [Moving downwards become upwards] ---3
# If the ball hits the Right wall it has to invert its velocity [Moving upwards become downwards] ---4