在乒乓球比赛中,有时球不会从球拍上弹起

2024-05-19 03:20:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的乒乓球游戏,大部分效果都很好。但有时会发生这样的情况:球不会从桨上弹起。球沿着桨叶摆动和滑动,桨叶似乎以磁力拉动球,如动画所示:

每当环绕球的矩形与桨叶矩形碰撞时,球的方向都会改变:

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()

Tags: andmoveifkeyswindowwidthpygameheight
1条回答
网友
1楼 · 发布于 2024-05-19 03:20:01

当球没有击中前面的球拍,而是击中顶部或底部时,就会发生这种行为。实际上,球拍和球之间的碰撞是被检测到的,方向也改变了。但是球深深地穿透了桨叶,以至于下一步球无法离开与桨叶的碰撞区域。这会导致在下一帧中再次检测到碰撞,并再次更改球的方向。现在,球的移动方向与第一次碰撞前相同。这个过程一直持续到球离开底部的桨叶。这会导致沿桨叶前侧发生之字形运动

有不同的解决方案。一个选项不是反转方向,而是在击打右拨杆时将方向设置为向左,并在击打左拨杆时将方向设置为向右:

if ball.colliderect(paddleLeft):
    move_x = abs(move_x)
if ball.colliderect(paddleRight):
    move_x = -abs(move_x) 

另一个选项是调整球的位置。如果右球拍被击中,球的右侧必须放在球拍的左侧。如果左侧球拍被击中,则必须将球的左侧置于球拍的右侧:

if ball.colliderect(paddleLeft):
    move_x *= -1
    ball.left = paddleLeft.right
if ball.colliderect(paddleRight):
    move_x *= -1
    ball.right = paddleRight.left

相关问题 更多 >

    热门问题