首页 > 解决方案 > Pong on pygame,尽管没有与桨相撞,球总是弹跳

问题描述

总的来说,我对编程并不陌生,这是我的第二场比赛,我很抱歉。我现在只用一个球拍做了一场乒乓球比赛,但即使没有击中球拍,球也会继续弹跳。这是我的抽奖球功能:

    def draw_ball(self): 
        self.sc.blit(ball, (self.bx,self.by))
        self.bx += self.speedx
        self.by += self.speedy

        if self.bx >= 1000:#check goals
            self.bx = 250
            self.by = 340

        if self.bx <= 38: #check coalision
            self.speedx *= -1
        if self.by<= 12: 
            self.speedy *= -1
        if  self.by>= 725: 
            self.speedy *= -1
        
        #check coalision with the paddle 
        #px and py are the coordinates of the paddle 
        if self.bx > (self.px - 35) and (self.by < (self.py + 196) and  (self.by + 38) > self.py) : 
            self.speedx *= -1

这是主循环:

#global variables
WIN_HEIGHT = 1024 
WIN_WIDTH = 768 
SPEED = 5 
PX = 956
PY  = 320 
MOVEMENT = 5
BALL = Ball(550, 60, screen, .5, .4, PX, PY)


running = True 
while running: 

  redraw_screen()

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      running = False
    mouse_pos = pygame.mouse.get_pos()
    if event.type == pygame.MOUSEBUTTONDOWN and START_BUTTON.is_clicked(mouse_pos):
      running = False
      playing = True

     while playing: 
        screen.fill((0,0,0))
        BALL.draw_ball()
        PLAYER.draw_player()
        pygame.display.flip()

        for event in pygame.event.get():
          if event.type == pygame.QUIT:
            running = False
            playing = False 

谢谢你的帮助。

标签: pythonpygamepong

解决方案


我建议使用pygame.Rect对象和方法.colliderect()

为球、桨和屏幕定义矩形或从 a 获取矩形pygame.Surface.get_rect()

ball_rect = ball.get_rect(topleft = (self.bx, self.by))
right_paddle_rect = pygame.Rect(self.px, self.py, 38, 196)
screen_rect = self.sc.get_rect()

测试小球与屏幕边框的碰撞:

if ball_rect.top < screen_rect.top or ball_rect.bottom > screen_rect.bottom:
    self.speedy *= -1
if ball_rect.left < screen_rect.left:
    self.speedx *= -1
if ball_rect.right > screen_rect.right:
    self.bx = 250
    self.by = 340

测试球和桨之间的碰撞时要小心。请参阅有时在乒乓球比赛中球不会从球拍上反弹

if ball_rect.colliderect(right_paddle_rect):
            self.speedx = -abs(self.speedx) 

完整方法draw_ball

def draw_ball(self):
    self.sc.blit(ball, (self.bx, self.by))

    self.bx += self.speedx
    self.by += self.speedy

    ball_rect = ball.get_rect(topleft = (self.bx, self.by))
    right_paddle_rect = pygame.Rect(self.px, self.py, 38, 196)
    screen_rect = self.sc.get_rect()

    if ball_rect.top < screen_rect.top or ball_rect.bottom > screen_rect.bottom:
        self.speedy *= -1
    if ball_rect.left < screen_rect.left:
        self.speedx *= -1
    if ball_rect.right > screen_rect.right:
        self.bx = 250
        self.by = 340

    if ball_rect.colliderect(right_paddle_rect):
        self.speedx = -abs(self.speedx) 

最小的例子:

import pygame

class Game:
    def __init__(self, screen):
        self.sc = screen
        self.bx, self.by = 250, 340
        self.speedx, self.speedy = 5, 5
        self.px, self.py = 700, 200

    def draw_ball(self):
        self.sc.blit(ball, (self.bx, self.by))

        self.bx += self.speedx
        self.by += self.speedy

        ball_rect = ball.get_rect(topleft = (self.bx, self.by))
        right_paddle_rect = pygame.Rect(self.px, self.py, 38, 196)
        screen_rect = self.sc.get_rect()

        if ball_rect.top < screen_rect.top or ball_rect.bottom > screen_rect.bottom:
            self.speedy *= -1
        if ball_rect.left < screen_rect.left:
            self.speedx *= -1
        if ball_rect.right > screen_rect.right:
            self.bx = 250
            self.by = 340

        if ball_rect.colliderect(right_paddle_rect):
            self.speedx = -abs(self.speedx) 

pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

ball = pygame.Surface((38, 38), pygame.SRCALPHA)
pygame.draw.circle(ball, (255, 255, 255), (19, 19), 19)
game = Game(screen)

run = True
while run:
    clock.tick(60)

    # event loop
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            print(pygame.key.name(event.key))

    keys = pygame.key.get_pressed()
    pspeed = 5
    if keys[pygame.K_UP]:
       game.py = max(0, game.py - pspeed) 
    if keys[pygame.K_DOWN]:
       game.py = min(screen.get_height()-196, game.py + pspeed) 

    screen.fill(0)
    game.draw_ball()
    pygame.draw.rect(screen, (255, 255, 255), (game.px, game.py, 38, 196)) 
    pygame.display.flip()

推荐阅读