Code for How to Build a Breakout Game with PyGame in Python Tutorial


View on Github

ball.py

import pygame as pg
from settings import ball_x_speed, ball_y_speed, ball_radius


class Ball:

    def __init__(self, x, y, screen):
        self.x = x
        self.y = y
        self.screen = screen
        self.radius = ball_radius
        self.color = pg.Color("grey")
        self.x_speed = ball_x_speed
        self.y_speed = ball_y_speed

    def move(self):
        pg.draw.circle(self.screen, self.color, [self.x, self.y], self.radius)
        self.y -= self.y_speed
        self.x -= self.x_speed

    def bounce_x(self):
        self.x_speed *= -1

    def bounce_y(self):
        self.y_speed *= -1

    def check_for_contact_on_x(self):
        if self.x - self.radius <= 0 or self.x + self.radius >= self.screen.get_width():
            self.bounce_x()

    def check_for_contact_on_y(self):
        if self.y + self.radius <= 0:
            self.bounce_y()

bricks.py

import random
import pygame as pg


class Bricks:
    def __init__(self, screen, width, height):
        self.screen = screen
        self.width = width
        self.height = height
        self.random_colors = ['blue', 'yellow', 'red', 'green', 'orange']
        self.bricks = []
        self.brick_colors = []
        self.set_values()

    def set_values(self):
        y_values = [int(y) for y in range(100, 200, 25)]
        x_values = [int(x) for x in range(10, 550, 42)]
        y_index = 0
        self.loop(x_values, y_values, y_index)

    def loop(self, x_values, y_values, y_index):

        for n in x_values:
            # Check if it is the last position in the x_values list.
            if n == x_values[-1]:

                # Check if all the positions in the y_values has been occupied
                if y_index < len(y_values) - 1:
                    y_index += 1

                    # Run the method again if there are still vacant positions.
                    self.loop(x_values, y_values, y_index)

            # Create new bricks
            else:
                x = n
                y = y_values[y_index]
                brick = pg.Rect(x, y, self.width, self.height)
                self.bricks.append(brick)
                self.brick_colors.append(random.choice(self.random_colors))

    def show_bricks(self):
        for loop in range(len(self.bricks)):
            brick = self.bricks[loop]
            color = self.brick_colors[loop]
            pg.draw.rect(self.screen, color, brick)

main.py

import pygame as pg
from paddle import Paddle
from bricks import Bricks
from ball import Ball
from scores import ScoreBoard
from settings import *


pg.init()


screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption("Breakout Game")

clock = pg.time.Clock()


# OBJECTS
pad = Paddle(paddle_x, paddle_y)
bricks = Bricks(screen, brick_width, brick_height)
ball = Ball(ball_x, ball_y, screen)
score = ScoreBoard(text_x, color, screen)
score.set_high_score()


sound_played = False
running = True
while running:
    screen.fill(BG_COLOR)
    score.show_scores()
    pad.appear(screen)
    bricks.show_bricks()

    # Check for quit game
    for event in pg.event.get():
        if event.type == pg.QUIT:
            # score.record_high_score()
            running = False

    # Check if there are more trials
    if score.is_game_over():
        if not sound_played:
            pg.mixer.Sound.play(game_end)
            sound_played = True
        score.game_over()

    # Check if all bricks are broken
    elif len(bricks.bricks) <= 0:
        if not sound_played:
            pg.mixer.Sound.play(win_game)
            sound_played = True
        score.success()

    else:
        ball.move()

    # Check if ball hits the x-axis above
    ball.check_for_contact_on_x()

    # Check if ball hits y-axis
    ball.check_for_contact_on_y()

    # Check if ball falls off
    if ball.y + ball.radius >= 580:
        pg.mixer.Sound.play(dropping_ball)
        ball.y = pad.y - ball.radius
        pg.time.delay(2000)
        score.trials -= 1
        ball.bounce_y()

    # Check if ball hits paddle
    if (pad.rect.y < ball.y + ball.radius < pad.rect.y + pad.height
            and
            pad.rect.x < ball.x + ball.radius < pad.rect.x + pad.width):

        pg.mixer.Sound.play(pad_hit)
        ball.bounce_y()
        ball.y = pad.y - ball.radius

    # Check if ball hits brick
    for brick in bricks.bricks:
        if brick.collidepoint(ball.x, ball.y - ball.radius) or brick.collidepoint(ball.x, ball.y + ball.radius):
            pg.mixer.Sound.play(brick_breaking)
            bricks.bricks.remove(brick)
            ball.bounce_y()
            score.score += 1

    # Check for key presses
    keys = pg.key.get_pressed()
    if keys[pg.K_RIGHT]:
        pad.move_right()

    if keys[pg.K_LEFT]:
        pad.move_left()

    # Restart game
    if keys[pg.K_0]:
        if score.is_game_over():
            score.score = 0
            score.trials = 5
            score.sound_played = False
            bricks.bricks.clear()
            bricks.set_values()

    pg.display.flip()
    clock.tick(60)

paddle.py

import pygame as pg
from settings import paddle_height, paddle_width


class Paddle:

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = paddle_width
        self.height = paddle_height
        self.rect = pg.Rect(self.x, self.y, self.width, self.height)
        self.color = pg.Color("white")

    def appear(self, screen):
        pg.draw.rect(screen, self.color, self.rect)

    def move_right(self):
        if self.rect.x + self.width <= 550:
            self.rect.x += 2

    def move_left(self):
        if self.rect.x >= 0:
            self.rect.x -= 2

scores.py

import pygame as pg


class ScoreBoard:
    def __init__(self, x, color, screen):
        self.screen = screen
        self.color = color
        self.x = x
        self.score = 0
        self.high_score = 0
        self.trials = 5
        self.font = pg.font.SysFont("calibri", 20)

    def show_scores(self):
        score_text = self.font.render(f"Score: {self.score}", True, self.color)
        high_score_text = self.font.render(f"High Score: {self.high_score}", True, self.color)
        trials_text = self.font.render(f"Trials: X{self.trials}", True, self.color)

        score_text_rect = score_text.get_rect(topleft=(self.x, 10))
        high_score_text_rect = high_score_text.get_rect(topleft=(self.x, 26))
        trials_text_rect = trials_text.get_rect(topleft=(self.x, 42))

        self.screen.blit(score_text, (self.x, 10))
        self.screen.blit(high_score_text, (self.x, 26))
        self.screen.blit(trials_text, (self.x, 42))

    def is_game_over(self):
        if self.trials == 0:
            return True
        return False

    def game_over(self):
        game_over_color = 'red'
        game_over_font = pg.font.SysFont("calibri", 30)
        game_over_text = game_over_font.render(f"Game Over! Click '0' to restart.", True, game_over_color)
        game_over_rect = game_over_text.get_rect(topright=(50, 300))
        self.screen.blit(game_over_text, (50, 300))
        self.record_high_score()

    def success(self):
        game_success_color = 'green'
        game_success_font = pg.font.SysFont("calibri", 30)
        game_success_text = game_success_font.render(f"You won! Click '0' to restart.", True, game_success_color)
        game_success_rect = game_success_text.get_rect(topleft=(50, 300))
        self.screen.blit(game_success_text, (50, 300))
        self.record_high_score()

    def set_high_score(self):
        try:
            with open("records.txt", mode="r") as file:
                lines = file.readlines()
        except FileNotFoundError:
            with open("records.txt", mode="w") as data:
                data.write("0")
                score = 0
        else:
            score = lines[0]

        self.high_score = int(score)

    def record_high_score(self):
        if self.score > self.high_score:
            with open("records.txt", mode="w") as file:
                file.write(f"{self.score}")

settings.py

import pygame as pg

# Initialize Sound
pg.mixer.init()

# Audio files
pad_hit = pg.mixer.Sound('audio/pad_hit.ogg')
brick_breaking = pg.mixer.Sound("audio/brick_breaking.ogg")
game_end = pg.mixer.Sound("audio/game_end_.ogg")
dropping_ball = pg.mixer.Sound("audio/dropping_ball.ogg")
win_game = pg.mixer.Sound("audio/win_game.ogg")


# Screen dimensions
WIDTH = 550
HEIGHT = 600

BG_COLOR = "purple"

# Text color
color = "white"


# Paddle settings
paddle_x = 200
paddle_y = 550
paddle_width = 100
paddle_height = 20


# Ball settings
ball_x = 250
ball_y = 540
ball_x_speed = 2
ball_y_speed = 2
ball_radius = 5


# Text settings
text_x = 300


# Bricks settings
brick_width = 40
brick_height = 20


pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy