This tutorial is the fifth tutorial in a series of five Pygame tutorials:
- Tutorial 1 – Getting Started with Pygame
- Tutorial 2 – Creating Sprites using Pygame
- Tutorial 3 – How to control your sprites
- Tutorial 4 – Adding More Sprites
- Tutorial 5 – Pygame – How-To’s
Now that you have completed your first game you may want to customise it further of or add extra functionalities. The following How-To’s tutorials may become quiet useful.
Also remember that a Pygame game will be based around the main program loop. Make sure you fully understand the structure of your main.py file:

To gain a better understanding of the Pygame library you should familiarise yourself with its main modules and classes.
View Pygame Framework
Before the main program loop add the following code:
background = pygame.image.load("images/background.png")
In your main program loop add the following code:
screen.blit(background, (0, 0))
In the above code (0,0) represents the (x,y) coordinates of where you would like your picture to appear.
The background has to be saved in your “images” folder.
myPicture = pygame.image.load("images/myPicture.png").convert_alpha()
font = pygame.font.Font(None, 36)
text = font.render("Hello World!", 1, (10, 10, 10))
screen.blit(text, (50,50))
mySprite.image = pygame.transform.flip(mySprite.image, True, False)
To flip your sprite vertically:
mySprite.image = pygame.transform.flip(mySprite.image, False, True)
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_RIGHT:
#do_something_here!
elif event.key == K_LEFT:
#do_something_here!
elif event.key == K_UP:
#do_something_here!
elif event.key == K_DOWN:
#do_something_here!
import pygame
pygame.init()
#Set the pygame window
screen = pygame.display.set_mode((600, 400))
class TextBox:
#Constructor
def __init__(self, x, y, w, h, fontSize=24, maxLength=100, resizable=True, text='', textColor=(0,0,0), borderColor=(40,120,180), activeBorderColor=(200,0,0)):
self.rect = pygame.Rect(x, y, w, h)
self.color = borderColor
self.inactiveColor = borderColor
self.textColor = textColor
self.activeColor = activeBorderColor
self.maxLength = maxLength
self.resizable = resizable
self.text = text
self.fontSize= fontSize
FONT = pygame.font.Font(None, self.fontSize)
self.txt_surface = FONT.render(text, True, self.color)
self.active = False
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
#Detects when the user clicks on the textbox
if self.rect.collidepoint(event.pos):
self.active = True
self.color = self.activeColor
else:
self.active = False
self.color = self.inactiveColor
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
#Clear text box
self.text = ''
elif event.key == pygame.K_BACKSPACE:
#Remove last character
self.text = self.text[:-1]
elif event.key in [pygame.K_TAB,pygame.K_ESCAPE]:
#Ignore = do nothing
pass
else:
#Append character
if len(self.text) < self.maxLength:
self.text += event.unicode
#Display text
FONT = pygame.font.Font(None, self.fontSize)
self.txt_surface = FONT.render(self.text, True, self.textColor)
def update(self):
# Resize the box if the text is too long.
if self.resizable:
width = max(200, self.txt_surface.get_width()+10)
self.rect.w = width
def draw(self, screen):
screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5))
pygame.draw.rect(screen, self.color, self.rect, 2)
#Main program starts here
#Textbox (x, y , width, height, fontSize, maxLength, resizeable, text, textColor, borderColor, activeBorderColor)
username = TextBox(200, 96, 200, 24, 24, 20, False)
password = TextBox(200, 146, 200, 24, 24, 20, False)
textboxes = [username, password]
font = pygame.font.Font(None, 24)
labelUsername = font.render("Username:", 1, (10, 10, 10))
labelPassword = font.render("Password:", 1, (10, 10, 10))
clock = pygame.time.Clock()
carryOn = True
#Main program loop
while carryOn:
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
for textbox in textboxes:
textbox.handle_event(event)
screen.fill((255, 255, 255))
screen.blit(labelUsername, (80,100))
screen.blit(labelPassword, (80,150))
for textbox in textboxes:
textbox.update()
textbox.draw(screen)
#print(username.text)
#print(password.text)
pygame.display.flip()
clock.tick(30)
pygame.quit()

In your main program, at the very top, just after the import pygame statement add the following code:
from pygame.locals import *
def getKey():
while 1:
event = pygame.event.poll()
if event.type == KEYDOWN:
return event.key
else:
pass
def popup(screen, message, width, height,x , y, bgcolor, textColor):
#Display a popup box in the middle of the screen
#This popup will only disappear when the user presses the Return key
fontobject = pygame.font.Font(None,18)
pygame.draw.rect(screen, bgcolor,
(x - width/2 +2,
y - height/2 +2,
300,36), 0)
pygame.draw.rect(screen, (255,255,255),
(x - width/2,
y - height/2,
304,40), 1)
if len(message) != 0:
screen.blit(fontobject.render(message, 1, textColor),
(x - width/2 + 10, y - height/2 + 14))
pygame.display.flip()
def askQuestion(screen, question, width=300, height=40, x=-1, y=-1, bgColor=(255,0,0), textColor=(255,255,255)):
#width, height, x, y, bgColor and textColor are optional arguments
#When x and y are omitted, use the centre of the screen
if x==-1:
x = screen.get_width() / 2
if y==-1:
y = screen.get_height() / 2
pygame.font.init()
current_string = []
popup(screen, question + ": " + "".join(current_string), width, height, x, y, bgColor, textColor)
upperCase=False
while 1:
inkey = getKey()
if inkey == K_BACKSPACE:
current_string = current_string[0:-1]
elif inkey == K_RETURN:
break
elif inkey == K_LSHIFT or inkey == K_RSHIFT:
upperCase=not upperCase #Switch between lowercase and uppercase when the shift key is pressed
elif inkey <= 255:
if (inkey>=97 and inkey<=122) and upperCase==True:
inkey-=32 #Convert to UPPERCASE
current_string.append(chr(inkey))
popup(screen, question + ": " + "".join(current_string), width, height, x, y, bgColor, textColor)
return "".join(current_string)
Then in your main program, whenever you want a new popup box use the following code:
answer = askQuestion(screen, "Type a question...")
Some arguments can be added:
answer = askQuestion(screen, "Login name?", width=300, height=40, x=100, y=100, bgColor=(255,0,0), textColor=(255,255,255))
if pygame.mouse.get_pressed()[0]:
mousex,mousey = event.pos
if playerCar.rect.collidepoint(mousex,mousey):
playerCar.rect.x=mousex-playerCar.rect.width/2
playerCar.rect.y=mousey-playerCar.rect.height/2
e.g.
GREEN == (0,255,0)
x=100
y=100
if screen.get_at((x, y)) == GREEN:
print("This pixel is green")
Code to add:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
while True: #Infinite loop that will be broken when the user press the space bar again
event = pygame.event.wait()
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
break #Exit infinite loop
if event.type == MOUSEMOTION:
x,y = event.pos
if playerCar.rect.collidepoint(x,y):
print "You clicked on the player's car"
for srite in all_comming_cars:
if sprite.rect.collidepoint(x,y):
print "You clicked on a car"
To do so, go in your sprite class (e.g. Car Class) and add the following line of code in the constructor (__init__() of the class):
self.mask = pygame.mask.from_surface(self.image)
For instance:
class Car(pygame.sprite.Sprite):
#This class represents a car. It derives from the "Sprite" class in Pygame.
def __init__(self, color, width, height, speed):
# Call the parent class (Sprite) constructor
super().__init__()
...
self.image = pygame.image.load("car.png").convert_alpha()
self.mask = pygame.mask.from_surface(self.image)
...
In your main code, use the following code to detect collisions:
#Check if there is a car collision
car_collision_list = pygame.sprite.spritecollide(playerCar,all_coming_cars,False,pygame.sprite.collide_mask)
for car in car_collision_list:
print("Car crash!")
#End Of Game
carryOn=False
At the start of your code (main.py), after importing the pygame library, add the following lines of code:
pygame.mixer.pre_init(frequency=44100, size=-16, channels=2, buffer=4096)
pygame.mixer.music.load('Sounds/soundtrack.mp3')
pygame.mixer.music.play(-1) #-1 means loops for ever, 0 means play just once)
Note that you can stop the music at any time using the following instruction:
pygame.mixer.music.stop()
You may prefer to pause the music:
pygame.mixer.music.pause()
… or unpause the music:
pygame.mixer.music.unpause()
effect = pygame.mixer.Sound('Sounds/beep.wav')
effect.play()
Did you like this challenge?
Click on a star to rate it!
Average rating 4.5 / 5. Vote count: 52
No votes so far! Be the first to rate this post.





