Learn Python by Building a Brick Breaker Game | Source Code Included

Faraz

By Faraz - May 28, 2023

Learn how to create a Brick Breaker game using Python with this step-by-step tutorial. Develop your Python skills while building a fun game. Source code included!


Brick Breaker Game Python Tutorial.jpg

Are you an aspiring Python developer looking to hone your programming skills while creating an engaging and interactive game? Look no further! In this comprehensive guide, we will walk you through the process of building a Brick Breaker game in Python, complete with the source code. By following our step-by-step instructions, you will not only gain a deeper understanding of Python programming but also create a captivating game that will entertain and challenge players of all ages.

Table of Contents

  1. Introduction
  2. Understanding the Brick Breaker Game
  3. Setting up the Development Environment
  4. Importing the Necessary Libraries
  5. Source Code
  6. Explanation of Source Code
  7. Conclusion
  8. FAQs

I. Introduction

Have you ever wanted to create your own game from scratch? In this article, we'll dive into the exciting world of game development and learn how to build a Brick Breaker game using Python. Brick Breaker is a classic arcade game where the player controls a paddle to bounce a ball and break bricks. By the end of this tutorial, you'll have a fully functional game that you can play and share with others. So let's get started!

II. Understanding the Brick Breaker Game

Before we begin coding, let's understand the basic concept of the Brick Breaker game. The game consists of a rectangular grid of bricks, a paddle, and a ball. The player controls the paddle horizontally at the bottom of the screen, using it to bounce the ball and prevent it from falling off the screen. The goal is to break all the bricks on the screen by repeatedly hitting them with the ball. As the player progresses, the game becomes more challenging with different layouts, power-ups, and obstacles.

III. Setting up the Development Environment

To build the Brick Breaker game, we need to set up our development environment. Follow these steps to get started:

  • Install Python: If you don't have Python installed on your system, download and install the latest version from the official Python website.
  • Install a Code Editor: Choose a code editor of your preference, such as Visual Studio Code, PyCharm, or Sublime Text.
  • Create a New Python Project: Open your code editor and create a new Python project. This will serve as the workspace for our game development.
  • Install Pygame: Pygame is a Python library that provides functionalities for creating games. Install it by running the following command in your command prompt or terminal:
    pip install pygame

IV. Importing the Necessary Libraries

In Python, we have access to various libraries that can help us simplify the game development process. For the Brick Breaker game, we'll be using the Pygame library, which provides functionality for creating games and multimedia applications. To import Pygame, use the following command:

import pygame
from pygame.locals import *

V. Source Code

import pygame
from pygame.locals import *

pygame.init()

'''
Defining gaming window size and font
'''
Window_width = 500
Window_height = 500

window = pygame.display.set_mode((Window_width, Window_height))
pygame.display.set_caption('Brickstroy')


font = pygame.font.SysFont('Arial', 30)

'''
Defining Bricks colour
'''
O_brick = (255, 100, 10)
w_brick = (255, 255, 255)
g_brick = (0, 255, 0)
black = (0, 0, 0)


game_rows = 6
game_coloumns = 6
clock = pygame.time.Clock()
frame_rate = 60
my_ball = False
game_over = 0
score = 0


class Ball():
    '''
Creating ball for the game
'''

    def __init__(self, x, y):

        self.radius = 10
        self.x = x - self.radius
        self.y = y - 50
        self.rect = Rect(self.x, self.y, self.radius * 2, self.radius * 2)
        self.x_speed = 4
        self.y_speed = -4
        self.max_speed = 5
        self.game_over = 0

    def motion(self):
        collision_threshold = 5
        block_object = Block.bricks
        brick_destroyed = 1
        count_row = 0
        for row in block_object:
            count_item = 0
            for item in row:
                # check collision with gaming window
                if self.rect.colliderect(item[0]):
                    if abs(self.rect.bottom - item[0].top) < collision_threshold and self.y_speed > 0:
                        self.y_speed *= -1

                    if abs(self.rect.top - item[0].bottom) < collision_threshold and self.y_speed < 0:
                        self.y_speed *= -1
                    if abs(self.rect.right - item[0].left) < collision_threshold and self.x_speed > 0:
                        self.x_speed *= -1
                    if abs(self.rect.left - item[0].right) < collision_threshold and self.x_speed < 0:
                        self.x_speed *= -1

                    if block_object[count_row][count_item][1] > 1:
                        block_object[count_row][count_item][1] -= 1
                    else:
                        block_object[count_row][count_item][0] = (0, 0, 0, 0)

                if block_object[count_row][count_item][0] != (0, 0, 0, 0):
                    brick_destroyed = 0
                count_item += 1
            count_row += 1

        if brick_destroyed == 1:
            self.game_over = 1

        # check for collision with bricks
        if self.rect.left < 0 or self.rect.right > Window_width:
            self.x_speed *= -1

        if self.rect.top < 0:
            self.y_speed *= -1
        if self.rect.bottom > Window_height:
            self.game_over = -1

        # check for collission with base
        if self.rect.colliderect(user_basepad):
            if abs(self.rect.bottom - user_basepad.rect.top) < collision_threshold and self.y_speed > 0:
                self.y_speed *= -1
                self.x_speed += user_basepad.direction
                if self.x_speed > self.max_speed:
                    self.x_speed = self.max_speed
                elif self.x_speed < 0 and self.x_speed < -self.max_speed:
                    self.x_speed = -self.max_speed
                else:
                    self.x_speed *= -1

        self.rect.x += self.x_speed
        self.rect.y += self.y_speed

        return self.game_over

    def draw(self):
        pygame.draw.circle(window, (0, 0, 255), (self.rect.x +
                           self.radius, self.rect.y + self.radius), self.radius)
        pygame.draw.circle(window, (255, 255, 255), (self.rect.x +
                           self.radius, self.rect.y + self.radius), self.radius, 1)

    def reset(self, x, y):

        self.radius = 10
        self.x = x - self.radius
        self.y = y - 50
        self.rect = Rect(self.x, self.y, self.radius * 2, self.radius * 2)
        self.x_speed = 4
        self.y_speed = -4
        self.max_speed = 5
        self.game_over = 0


class Block():
    '''
This class will help me create Blocks/bricks of the game
'''

    def __init__(self):
        self.width = Window_width // game_coloumns
        self.height = 40

    def make_brick(self):
        self.bricks = []
        single_brick = []
        for row in range(game_rows):

            brick_row = []

            for coloumn in range(game_coloumns):

                x_brick = coloumn * self.width
                y_brick = row * self.height
                rect = pygame.Rect(x_brick, y_brick, self.width, self.height)
                # assign power to the bricks based on row
                if row < 2:
                    power = 3
                elif row < 4:
                    power = 2
                elif row < 6:
                    power = 1

                single_brick = [rect, power]

                brick_row.append(single_brick)

            self.bricks.append(brick_row)

    def draw_brick(self):
        for row in self.bricks:
            for brick in row:

                if brick[1] == 3:
                    brick_colour = O_brick
                elif brick[1] == 2:
                    brick_colour = w_brick
                elif brick[1] == 1:
                    brick_colour = g_brick
                pygame.draw.rect(window, brick_colour, brick[0])
                pygame.draw.rect(window, black, (brick[0]), 1)


class base():
    '''
This class is to create the base pad of the game
'''

    def __init__(self):

        self.height = 20
        self.width = int(Window_width / game_coloumns)
        self.x = int((Window_width / 2) - (self.width / 2))
        self.y = Window_height - (self.height * 2)
        self.speed = 8
        self.rect = Rect(self.x, self.y, self.width, self.height)
        self.direction = 0

    def slide(self):

        self.direction = 0
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.x -= self.speed
            self.direction = -1
        if key[pygame.K_RIGHT] and self.rect.right < Window_width:
            self.rect.x += self.speed
            self.direction = 1

    def draw(self):
        pygame.draw.rect(window, (0, 0, 255), self.rect)
        pygame.draw.rect(window, (255, 255, 255), self.rect, 1)

    def reset(self):

        self.height = 20
        self.width = int(Window_width / game_coloumns)
        self.x = int((Window_width / 2) - (self.width / 2))
        self.y = Window_height - (self.height * 2)
        self.speed = 8
        self.rect = Rect(self.x, self.y, self.width, self.height)
        self.direction = 0


def draw_text(text, font, w_brick, x, y):
    '''
    Funtion for showing text in gaming window
    '''
    image = font.render(text, True, w_brick)
    window.blit(image, (x, y))


Block = Block()
# Creating Brick
Block.make_brick()
# Defining base pad
user_basepad = base()
ball = Ball(user_basepad.x + (user_basepad.width // 2),
            user_basepad.y - user_basepad.height)   # Defining ball

game = True
while game:

    clock.tick(frame_rate)
    window.fill(black)                           # Gaming window Background
    Block.draw_brick()                           # Drawing bricks
    user_basepad.draw()                          # Drawing user basepad
    ball.draw()                                  # Drawing gaming ball

    if my_ball:
        user_basepad.slide()
        game_over = ball.motion()
        if game_over != 0:
            my_ball = False

    # Game Info on the gaming window
    if not my_ball:
        if game_over == 0:
            draw_text('CLICK ANYWHERE TO START', font,
                      w_brick, 90, Window_height // 2 + 100)
        elif game_over == 1:
            draw_text('YOU WON!', font, w_brick, 180, Window_height // 2 + 50)
            draw_text('CLICK ANYWHERE TO RESTART', font,
                      w_brick, 90, Window_height // 2 + 100)
        elif game_over == -1:
            draw_text('GAME OVER!', font, w_brick,
                      180, Window_height // 2 + 50)
            draw_text('CLICK ANYWHERE TO RESTART', font,
                      w_brick, 90, Window_height // 2 + 100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game = False
        if event.type == pygame.MOUSEBUTTONDOWN and my_ball == False:
            my_ball = True
            ball.reset(user_basepad.x + (user_basepad.width // 2),
                       user_basepad.y - user_basepad.height)
            user_basepad.reset()
            Block.make_brick()

    pygame.display.update()

pygame.quit()

VI. Explanation of Source Code

Let's go through the code step by step:

1. Importing Libraries:

  • The code begins by importing the necessary libraries, specifically pygame and pygame.locals. These libraries provide functionality for developing games and handling keyboard/mouse events.

2. Initializing Pygame:

  • pygame.init() initializes the pygame module and prepares it for use.

3. Defining Window Size and Font:

  • The code sets the dimensions of the game window by defining Window_width and Window_height.
  • The window variable is created using pygame.display.set_mode() with the specified window dimensions.
  • The window's caption is set to 'Brickstroy' using pygame.display.set_caption().
  • The font variable is created using pygame.font.SysFont() to define the font style and size for text rendering.

4. Defining Brick Colors:

  • Several color variables are defined using RGB values to represent different brick colors: O_brick, w_brick, g_brick, and black.

5. Setting Game Parameters:

  • The code sets various game parameters such as the number of rows and columns (game_rows and game_columns), the frame rate, and initializes variables like my_ball (game ball status), game_over (game over status), and score (player score).

6. Creating Classes: Ball, Block, and Base

  • The code defines three classes to represent game objects: Ball, Block, and Base.
  • Ball Class:
    • The Ball class represents the game ball and its behavior.
    • The __init__ method initializes the ball's properties such as position, radius, speed, and game over status.
    • The motion method handles the ball's movement and collision detection with bricks, the game window, and the base pad.
    • The draw method renders the ball on the game window.
    • The reset method resets the ball's properties to their initial values.
  • Block Class:
    • The Block class represents the bricks in the game.
    • The __init__ method initializes the brick's width and height.
    • The make_brick method generates the arrangement of bricks based on the game's rows and columns.
    • The draw_brick method renders the bricks on the game window.
  • Base Class:
    • The Base class represents the base pad controlled by the player.
    • The __init__ method initializes the base pad's properties such as position, size, speed, and direction.
    • The slide method updates the base pad's position based on user input.
    • The draw method renders the base pad on the game window.
    • The reset method resets the base pad's properties to their initial values.

7. Helper Function: draw_text

  • The draw_text function is a helper function that renders text on the game window using the specified font, color, position, and content.

8. Creating Game Objects:

  • Instances of the Block, Base, and Ball classes are created: Block, user_basepad, and ball, respectively.
  • The Block object is used to generate the arrangement of bricks using the make_brick method.

9. Game Loop:

  • The main game loop is started using a while loop with the condition game to control the game flow.
  • Inside the game loop, the frame rate is controlled using clock.tick(frame_rate).
  • The game window is filled with black color using window.fill(black).
  • The bricks, base pad, and ball are drawn on the game window using their respective draw methods.
  • The game status is checked to display appropriate messages on the game window.
  • Various events, such as quitting the game or starting a new game, are handled within the event loop.
  • Finally, the updated display is rendered on the screen using pygame.display.update().

10. Exiting the Game:

  • Once the game loop is exited (when game becomes False), Pygame is terminated using pygame.quit().

VII. Conclusion

Congratulations on completing this tutorial on building a Brick Breaker game in Python! You have learned essential concepts and techniques in Python game development and have successfully created a fully functional game from scratch.

Throughout this tutorial, you have gained hands-on experience in setting up the development environment, designing game objects, implementing game logic, handling user input, adding sound effects, and testing the game. By following the step-by-step instructions and exploring the provided source code, you have not only built a Brick Breaker game but also deepened your understanding of programming principles and game development techniques.

Now that you have a solid foundation in Python game programming, you can further enhance the game and experiment with additional features. Consider implementing power-ups, different levels with varying difficulties, or even multiplayer functionality. The possibilities are endless, and this tutorial serves as a launching pad for your creativity and exploration in game development.

Remember to continue practicing and exploring other game development concepts and technologies. The world of game development offers a wide range of opportunities, and Python provides a versatile platform for creating all kinds of games.

We hope this tutorial has been informative and enjoyable for you. Building games is not only a great way to learn programming but also a rewarding experience that allows you to bring your ideas to life. Don't hesitate to share your creations with others and continue to expand your skills.

Thank you for joining us on this journey to build a Brick Breaker game in Python. We wish you the best of luck in your future game development endeavors. Keep coding and have fun!

VIII. FAQs

Q: Can I customize the game graphics and colors?

A: Absolutely! You can modify the game graphics and colors to suit your preferences. Pygame provides various functions and methods to draw shapes, load images, and apply different colors.

Q: How can I add more levels to the game?

A: To add more levels, you can create additional layouts of bricks with increasing difficulty. You'll need to implement the logic to switch between levels and keep track of the player's progress.

Q: Is it possible to add power-ups or special abilities to the game?

A: Yes, you can introduce power-ups or special abilities by creating new game objects and defining their behaviors. For example, a power-up could make the paddle larger or give the player an extra life.

Q: Can I create a multiplayer version of the game?

A: While this tutorial focuses on building a single-player game, it's definitely possible to create a multiplayer version. You would need to implement network communication and synchronization between players.

Q: How can I optimize the game's performance?

A: To optimize the game's performance, you can explore techniques such as efficient collision detection algorithms, minimizing unnecessary computations, and optimizing resource usage.

That’s a wrap!

I hope you enjoyed this article

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post