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 yuou should familiarise yourself with its main modules and classes.
View Pygame Framework
Before the main program loop add the following code:
1 |
background = pygame.image.load("images/background.png") |
In your main program loop add the following code:
1 |
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.
1 |
myPicture = pygame.image.load("images/myPicture.png").convert_alpha() |
1 2 3 |
font = pygame.font.Font(None, 36) text = font.render("Hello World!", 1, (10, 10, 10)) screen.blit(text, (50,50)) |
1 |
mySprite.image = pygame.transform.flip(mySprite.image, True, False) |
To flip your sprite vertically:
1 |
mySprite.image = pygame.transform.flip(mySprite.image, False, True) |
1 2 3 4 5 6 7 8 9 10 |
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! |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
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:
1 |
answer = askQuestion(screen, "Type a question...") |
Some arguments can be added:
1 |
answer = askQuestion(screen, "Login name?", width=300, height=40, x=100, y=100, bgColor=(255,0,0), textColor=(255,255,255)) |
1 2 3 4 5 |
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.
1 2 3 4 5 |
GREEN == (0,255,0) x=100 y=100 if screen.get_at((x, y)) == GREEN: print("This pixel is green") |
Code to add:
1 2 3 4 5 |
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 |
1 2 3 4 5 6 7 8 9 |
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):
1 |
self.mask = pygame.mask.from_surface(self.image) |
For instance:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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:
1 2 3 4 5 6 |
#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:
1 2 3 |
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:
1 |
pygame.mixer.music.stop() |
You may prefer to pause the music:
1 |
pygame.mixer.music.pause() |
… or unpause the music:
1 |
pygame.mixer.music.unpause() |
1 2 |
effect = pygame.mixer.Sound('Sounds/beep.wav') effect.play() |