ball.py
import pygame, sys
import random
from settings import WIDTH, HEIGHT
pygame.init()
class Ball:
def __init__(self, x, y, radius):
self.x = x
self.y = y
self.radius = radius
self.rect = pygame.Rect(self.x, self.y, radius, radius)
self.color = pygame.Color("red")
self.direction = None
self.speed_x = 0
self.speed_y = 0
self._random_direction()
def _random_direction(self):
direction = ("right", "left")
self.direction = random.choice(direction)
def _ball_movement(self):
# horizontal handling
if self.direction == "right":
self.speed_x = 18
else:
self.speed_x = -18
# vertical handling
if self.rect.y >= HEIGHT - self.radius:
self.speed_y = -18
elif self.rect.y <= 0 + self.radius:
self.speed_y = 18
# wall bounce handling
self.rect.x += self.speed_x
self.rect.y += self.speed_y
def update(self, screen):
self._ball_movement()
pygame.draw.rect(screen, self.color, self.rect)
main.py
import pygame, sys
from settings import WIDTH, HEIGHT
from table import Table
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Ping Pong")
class Pong:
def __init__(self, screen):
self.screen = screen
self.FPS = pygame.time.Clock()
def draw(self):
pygame.display.flip()
def main(self):
# start menu here
table = Table(self.screen) # pass to table the player_option saved to table.game_mode
while True:
self.screen.fill("black")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
table.player_move()
table.update()
self.draw()
self.FPS.tick(30)
if __name__ == "__main__":
play = Pong(screen)
play.main()
player.py
import pygame
class Player:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.rect = pygame.Rect(self.x, self.y, width, height)
self.color = pygame.Color("gray")
self.player_speed = 16
self.score = 0
def move_up(self):
self.rect.y -= self.player_speed
def move_bottom(self):
self.rect.y += self.player_speed
def update(self, screen):
pygame.draw.rect(screen, self.color, self.rect)
settings.py
WIDTH, HEIGHT = 990, 450
player_width, player_height = 20, 90
table.py
import pygame, time
import sys
from player import Player
from ball import Ball
from settings import WIDTH, HEIGHT, player_width, player_height
class Table:
def __init__(self, screen):
self.screen = screen
self.game_over = False
self.score_limit = 10
self.winner = None
self._generate_world()
# text info
self.font = pygame.font.SysFont('Bauhaus 93', 60)
self.inst_font = pygame.font.SysFont('Bauhaus 93', 30)
self.color = pygame.Color("white")
# create and add player to the screen
def _generate_world(self):
self.playerA = Player(0, HEIGHT // 2 - (player_height // 2), player_width, player_height)
self.playerB = Player(WIDTH - player_width, HEIGHT // 2 - (player_height // 2), player_width, player_height)
self.ball = Ball(WIDTH // 2 - player_width, HEIGHT - player_width, player_width)
def _ball_hit(self):
# if ball is not hit by a player and pass through table sides
if self.ball.rect.left >= WIDTH:
self.playerA.score += 1
self.ball.rect.x = WIDTH // 2
time.sleep(1)
elif self.ball.rect.right <= 0:
self.playerB.score += 1
self.ball.rect.x = WIDTH // 2
time.sleep(1)
# if ball land in the player
if pygame.Rect.colliderect(self.ball.rect, self.playerA.rect):
self.ball.direction = "right"
if pygame.Rect.colliderect(self.ball.rect, self.playerB.rect):
self.ball.direction = "left"
def _bot_opponent(self):
if self.ball.direction == "left" and self.ball.rect.centery != self.playerA.rect.centery:
if self.ball.rect.top <= self.playerA.rect.top:
if self.playerA.rect.top > 0:
self.playerA.move_up()
if self.ball.rect.bottom >= self.playerA.rect.bottom:
if self.playerA.rect.bottom < HEIGHT:
self.playerA.move_bottom()
def player_move(self):
keys = pygame.key.get_pressed()
# for bot opponent controls
self._bot_opponent()
# for player controls
if keys[pygame.K_UP]:
if self.playerB.rect.top > 0:
self.playerB.move_up()
if keys[pygame.K_DOWN]:
if self.playerB.rect.bottom < HEIGHT:
self.playerB.move_bottom()
def _show_score(self):
A_score, B_score = str(self.playerA.score), str(self.playerB.score)
A_score = self.font.render(A_score, True, self.color)
B_score = self.font.render(B_score, True, self.color)
self.screen.blit(A_score, (WIDTH // 4, 50))
self.screen.blit(B_score, ((WIDTH // 4) * 3, 50))
def _game_end(self):
if self.winner != None:
print(f"{self.winner} wins!!")
pygame.quit()
sys.exit()
def update(self):
self._show_score()
self.playerA.update(self.screen)
self.playerB.update(self.screen)
self._ball_hit()
if self.playerA.score == self.score_limit:
self.winner = "Opponent"
elif self.playerB.score == self.score_limit:
self.winner = "You"
self._game_end()
self.ball.update(self.screen)