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:
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.4 / 5. Vote count: 36
No votes so far! Be the first to rate this post.