I'm building a Pong game in Python with PyGame. For some reason, the ball in the game doesn't bounce off the walls / screen edges sometimes. It bounces off the walls once or twice and stops.
I don't know why that happens.
Could someone check my code to see if there are any errors?
import os
import pygame
WIDTH = 600
HEIGHT = 500
class Slider:
def __init__(self, x, y):
self.x = x
self.y = y
self.height = 120
self.width = 8
def draw(self, win):
pygame.draw.rect(win, (0, 255, 64), (self.x, self.y, self.width, self.height))
def move(self, dir, dis):
if dir == 'top' and self.y >= 0:
self.y -= dis
elif dir == 'bottom' and self.y <= 379:
self.y += dis
else:
self.y = self.y
class Ball:
def __init__(self, x, y):
self.x = x
self.y = y
self.radius = 15
self.speedY = 0.2
self.speedX = 0.2
self.top = y
self.bottom = y + 30
self.left = x
self.right = x + 30
def draw(self, win):
ball = pygame.draw.circle(win, (255, 255, 0), (self.x, self.y), self.radius)
self.top = ball.top
self.bottom = ball.bottom
self.left = ball.left
self.right = ball.right
def move(self):
if self.top <= 0:
self.speedY *= -1
else:
self.y += self.speedY
self.x += self.speedX
if self.bottom >= HEIGHT:
self.speedY *= -1
else:
self.y += self.speedY
self.x += self.speedX
if self.left <= 0:
self.speedX *= -1
else:
self.y += self.speedY
self.x += self.speedX
if self.right >= WIDTH:
self.speedX *= -1
else:
self.y += self.speedY
self.x += self.speedX
def draw_window(win, *sprites):
pygame.display.update()
win.fill((0, 0, 0, 0))
for sprite in sprites:
sprite.draw(win)
def main():
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Pong Game')
slider1 = Slider(100, 250)
slider2 = Slider(500, 250)
ball = Ball(300, 250)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
slider1.move('bottom', 0.3)
elif event.key == pygame.K_UP:
slider1.move('top', 0.3)
else:
print(pygame.key.name(event.key))
ball.move()
key = pygame.key.get_pressed()
if key[pygame.K_s]:
slider2.move('bottom', 0.3)
elif key[pygame.K_w]:
slider2.move('top', 0.3)
draw_window(win, slider1, slider2, ball)
pygame.quit()
quit()
main()
You need to change your move
method a bit, you need to remove the else
blocks as they mess up ball's movement, just always move the ball once when calling move
. You can also combine checking whether ball is on edge for an axis in one line (using or
):
def move(self):
if self.top <= 0 or self.bottom >= HEIGHT:
self.speedY *= -1
if self.left <= 0 or self.right >= WIDTH:
self.speedX *= -1
self.y += self.speedY
self.x += self.speedX