问题描述
我有一个简单的乒乓球游戏,效果很好.但有时会发生球不反弹的桨.球沿着桨摇晃和滑动,桨似乎在磁力拉球,如动画所示:
I have a simple pong game that mostly works well. But sometimes it occurs the the ball doesn't bounce of the paddle. The ball wobbles and slides along the paddle and the paddle seems to magnetically pull the ball as shown in the animation:
每当围绕球的矩形与桨形矩形碰撞时,球的方向都会改变:
Every time when the rectangle which surrounds the ball, collides the the paddle rectangle, the the direction of the ball is changed:
if ball.colliderect(paddleLeft):
move_x *=-1
if ball.colliderect(paddleRight):
move_x *=-1
是什么导致了这种行为?
What causes the behavior?
可以使用以下完整、最小且可验证的示例重现该问题.设置球的位置,以便在不移动右桨的情况下立即发生错误行为:
The issue can be reproduced with the following complete, minimal and verifiable example. The position of the ball is set so that the wrong behavior occurs immediately if the right paddle is not moved:
import pygame
pygame.init()
width, height = 600, 400
window = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
radius, move_x, move_y = 10, 3, 3
ball = pygame.Rect(width//2+125, 20, radius*2, radius)
paddleHeight = 80
paddleLeft = pygame.Rect(20, (height-paddleHeight)//2, 10, paddleHeight)
paddleRight = pygame.Rect(width-30, (height-paddleHeight)//2, 10, paddleHeight)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT: run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and paddleLeft.top > 0: paddleLeft.y -= 5
if keys[pygame.K_s] and paddleLeft.bottom < height: paddleLeft.y += 5
if keys[pygame.K_UP] and paddleRight.top > 0: paddleRight.y -= 5
if keys[pygame.K_DOWN] and paddleRight.bottom < height: paddleRight.y += 5
ball.x += move_x
ball.y += move_y
if ball.left <= 0 or ball.right >= width: move_x *=-1
if ball.top <= 0 or ball.bottom >= height: move_y *=-1
if ball.colliderect(paddleLeft): move_x *=-1
if ball.colliderect(paddleRight): move_x *=-1
window.fill(0)
pygame.draw.rect(window, (255, 255, 255), paddleLeft)
pygame.draw.rect(window, (255, 255, 255), paddleRight)
pygame.draw.circle(window, (255, 255, 255), ball.center, radius)
pygame.display.flip()
推荐答案
当球没有击中球拍的前部,而是击中球拍的顶部或底部时,就会发生这种情况.实际上检测到桨和球之间的碰撞并改变方向.但是球深深地刺入了球拍,以致球无法与球拍一起离开碰撞区域,然后进行下一步.这会导致在下一帧中再次检测到碰撞并再次改变球的方向.现在球的移动方向与第一次碰撞前的方向相同.这个过程一直持续到球离开底部的球拍.这会导致桨叶前侧的锯齿形运动.
The behavior occurs, when the ball doesn't hit the paddle at the front, but at the top or bottom. Actually the collision between the paddle and the ball is detected and the direction is changed. But the ball penetrated so deep into the paddle that the ball cannot leave the collision area with the paddle with it's next step. This causes that a collision is detected again in the next frame and the direction of the ball is changed again. Now the ball moves in the same direction as before the first collision. This process continues until the ball leaves the paddle at the bottom. This causes a zig zag movement along the front side of the paddle.
有不同的解决方案.一种选择是不反转方向,而是在击中右桨时将方向设置为向左,并在击中左桨时将方向设置为向右:
There are different solution. One option is not to reverse the direction, but to set the direction to the left when the right paddle is hit a nd to set the direction to the right when the left paddle is hit:
if ball.colliderect(paddleLeft):
move_x = abs(move_x)
if ball.colliderect(paddleRight):
move_x = -abs(move_x)
另一种选择是调整球的位置.如果击中右侧球拍,则球的右侧必须放在球拍的左侧.如果左桨被击中,那么球的左侧必须放在桨的右侧:
Another option is to adjust the position to the ball. If the right paddle is hit, the right side of the ball must be placed to the left of the paddle. If the left paddle is hit, then the left side of the ball must be placed to the right of the paddle:
if ball.colliderect(paddleLeft):
move_x *= -1
ball.left = paddleLeft.right
if ball.colliderect(paddleRight):
move_x *= -1
ball.right = paddleRight.left
这篇关于有时在乒乓球比赛中球不会从球拍上反弹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!