This tutorial is the second tutorial in a series of five Pygame tutorials:
- Breakout Tutorial 1: Getting Started
- Breakout Tutorial 2: Adding the Paddle
- Breakout Tutorial 3: Controlling the Paddle
- Breakout Tutorial 4: Adding a Bouncing Ball
- Breakout Tutorial 5: Adding a Brick Wall
- Extra: Pygame How To’s?
The final stage of our tutorial focuses on adding a brick wall and a scoring system to our Breakout game:
- The player will score a point if the ball bounces against a brick.
- The player will lose a life if the ball bounces against the bottom edge of the screen.
- Both the score and number of lives will be displayed at the top of the screen.
- A “Level Complete” message will be displayed if all bricks have been removed.
The final code for the main.py is provided below. We made several changes to the code as follows:
- On line 6 we import the Brick class. (Code provided in the brick.py tab)
- On lines 39 to 57 we create three rows of bricks and add them to a group called all_bricks.
- On lines 93 to 103 we take a life away when the ball hit the bottom edge of the screen. If the number of lives reaches zero, we display a “Game Over” message..
- On lines 114 to 129 we detect if the ball hits a brick. If so we remove the brick (using the kill() method) and increment the score by one.
#Import the pygame library and initialise the game engine
import pygame
#Let's import the Paddle Class & the Ball Class
from paddle import Paddle
from ball import Ball
from brick import Brick
pygame.init()
# Define some colors
WHITE = (255,255,255)
DARKBLUE = (36,90,190)
LIGHTBLUE = (0,176,240)
RED = (255,0,0)
ORANGE = (255,100,0)
YELLOW = (255,255,0)
score = 0
lives = 3
# Open a new window
size = (800, 600)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Breakout Game")
#This will be a list that will contain all the sprites we intend to use in our game.
all_sprites_list = pygame.sprite.Group()
#Create the Paddle
paddle = Paddle(LIGHTBLUE, 100, 10)
paddle.rect.x = 350
paddle.rect.y = 560
#Create the ball sprite
ball = Ball(WHITE,10,10)
ball.rect.x = 345
ball.rect.y = 195
all_bricks = pygame.sprite.Group()
for i in range(7):
brick = Brick(RED,80,30)
brick.rect.x = 60 + i* 100
brick.rect.y = 60
all_sprites_list.add(brick)
all_bricks.add(brick)
for i in range(7):
brick = Brick(ORANGE,80,30)
brick.rect.x = 60 + i* 100
brick.rect.y = 100
all_sprites_list.add(brick)
all_bricks.add(brick)
for i in range(7):
brick = Brick(YELLOW,80,30)
brick.rect.x = 60 + i* 100
brick.rect.y = 140
all_sprites_list.add(brick)
all_bricks.add(brick)
# Add the paddle and the ball to the list of sprites
all_sprites_list.add(paddle)
all_sprites_list.add(ball)
# The loop will carry on until the user exits the game (e.g. clicks the close button).
carryOn = True
# The clock will be used to control how fast the screen updates
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while carryOn:
# --- Main event loop
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
carryOn = False # Flag that we are done so we exit this loop
#Moving the paddle when the use uses the arrow keys
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
paddle.moveLeft(5)
if keys[pygame.K_RIGHT]:
paddle.moveRight(5)
# --- Game logic should go here
all_sprites_list.update()
#Check if the ball is bouncing against any of the 4 walls:
if ball.rect.x>=790:
ball.velocity[0] = -ball.velocity[0]
if ball.rect.x<=0:
ball.velocity[0] = -ball.velocity[0]
if ball.rect.y>590:
ball.velocity[1] = -ball.velocity[1]
lives -= 1
if lives == 0:
#Display Game Over Message for 3 seconds
font = pygame.font.Font(None, 74)
text = font.render("GAME OVER", 1, WHITE)
screen.blit(text, (250,300))
pygame.display.flip()
pygame.time.wait(3000)
#Stop the Game
carryOn=False
if ball.rect.y<40:
ball.velocity[1] = -ball.velocity[1]
#Detect collisions between the ball and the paddles
if pygame.sprite.collide_mask(ball, paddle):
ball.rect.x -= ball.velocity[0]
ball.rect.y -= ball.velocity[1]
ball.bounce()
#Check if there is the ball collides with any of bricks
brick_collision_list = pygame.sprite.spritecollide(ball,all_bricks,False)
for brick in brick_collision_list:
ball.bounce()
score += 1
brick.kill()
if len(all_bricks)==0:
#Display Level Complete Message for 3 seconds
font = pygame.font.Font(None, 74)
text = font.render("LEVEL COMPLETE", 1, WHITE)
screen.blit(text, (200,300))
pygame.display.flip()
pygame.time.wait(3000)
#Stop the Game
carryOn=False
# --- Drawing code should go here
# First, clear the screen to dark blue.
screen.fill(DARKBLUE)
pygame.draw.line(screen, WHITE, [0, 38], [800, 38], 2)
#Display the score and the number of lives at the top of the screen
font = pygame.font.Font(None, 34)
text = font.render("Score: " + str(score), 1, WHITE)
screen.blit(text, (20,10))
text = font.render("Lives: " + str(lives), 1, WHITE)
screen.blit(text, (650,10))
#Now let's draw all the sprites in one go. (For now we only have 2 sprites!)
all_sprites_list.draw(screen)
# --- Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# --- Limit to 60 frames per second
clock.tick(60)
#Once we have exited the main program loop we can stop the game engine:
pygame.quit()
import pygame
BLACK = (0,0,0)
class Paddle(pygame.sprite.Sprite):
#This class represents a paddle. It derives from the "Sprite" class in Pygame.
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the paddle, its width and height.
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(BLACK)
self.image.set_colorkey(BLACK)
# Draw the paddle (a rectangle!)
pygame.draw.rect(self.image, color, [0, 0, width, height])
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()
def moveLeft(self, pixels):
self.rect.x -= pixels
#Check that you are not going too far (off the screen)
if self.rect.x < 0:
self.rect.x = 0
def moveRight(self, pixels):
self.rect.x += pixels
#Check that you are not going too far (off the screen)
if self.rect.x > 700:
self.rect.x = 700
import pygame
from random import randint
BLACK = (0, 0, 0)
class Ball(pygame.sprite.Sprite):
#This class represents a ball. It derives from the "Sprite" class in Pygame.
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the ball, its width and height.
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(BLACK)
self.image.set_colorkey(BLACK)
# Draw the ball (a rectangle!)
pygame.draw.rect(self.image, color, [0, 0, width, height])
self.velocity = [randint(4,8),randint(-8,8)]
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()
def update(self):
self.rect.x += self.velocity[0]
self.rect.y += self.velocity[1]
def bounce(self):
self.velocity[0] = -self.velocity[0]
self.velocity[1] = randint(-8,8)
import pygame
BLACK = (0,0,0)
class Brick(pygame.sprite.Sprite):
#This class represents a brick. It derives from the "Sprite" class in Pygame.
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the brick, and its x and y position, width and height.
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(BLACK)
self.image.set_colorkey(BLACK)
# Draw the brick (a rectangle!)
pygame.draw.rect(self.image, color, [0, 0, width, height])
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()





Let’s look at the code for our main program. You may remember that in the first tutorial we talked about the main program loop. The first section of this loop is to respond to events such as user interactions when the user uses the mouse or the keyboard.









