我有一个简单的乒乓球游戏,大部分效果都很好。但有时会发生这样的情况:球不会从桨上弹起。球沿着桨叶摆动和滑动,桨叶似乎以磁力拉动球,如动画所示:
每当环绕球的矩形与桨叶矩形碰撞时,球的方向都会改变:
if ball.colliderect(paddleLeft):
move_x *=-1
if ball.colliderect(paddleRight):
move_x *=-1
是什么导致了这种行为
该问题可通过以下完整、最少且可验证的示例重现。设置球的位置,以便在右拨杆未移动时立即发生错误行为:
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()
当球没有击中前面的球拍,而是击中顶部或底部时,就会发生这种行为。实际上,球拍和球之间的碰撞是被检测到的,方向也改变了。但是球深深地穿透了桨叶,以至于下一步球无法离开与桨叶的碰撞区域。这会导致在下一帧中再次检测到碰撞,并再次更改球的方向。现在,球的移动方向与第一次碰撞前相同。这个过程一直持续到球离开底部的桨叶。这会导致沿桨叶前侧发生之字形运动
有不同的解决方案。一个选项不是反转方向,而是在击打右拨杆时将方向设置为向左,并在击打左拨杆时将方向设置为向右:
另一个选项是调整球的位置。如果右球拍被击中,球的右侧必须放在球拍的左侧。如果左侧球拍被击中,则必须将球的左侧置于球拍的右侧:
相关问题 更多 >
编程相关推荐