Table of Contents
Step 007 - Loading Files, Subsurfaces, Dirty Rects
In this step, you will learn how to load images from files (and from a subfolder) and how to work with pygame's subsurfaces.
If you manage to install and run step007.py correctly (see instructions below) you see a pygame snake wandering over one of my pictures, referred as “ugly background”. But in the left corner, you see a tv-like screen showing the subsurface of a more pretty picture (referred as “pretty background”), The Birth of Venus, from Italian renessance painter Sandro Botticelli (1454-1510).
- To let the snake over-“paint” the ugly picture with the pretty picture, toggle P.
- To let the snake draw a “trace”, toggle D
- To restore the ugly background, press C
Loading Images (from Subfolder)
This code example needs image files and those image files need to be loaded into pygame.
Loading a surface from a picture file is not very complicated:
mypicture = pygame.image.load("picturefile.jpg") # simple method if picture in same folder
Stuffing each and every file for your program into one giant folder and letting the poor user figure out how to start your game is bad style. Good style is to stuff just one python start file and maybe some readme files into one folder and everything else (sounds, images, modules) into a sub-folder.
The next code example show you how to access images inside a sub-folder. Because each operating system has another way of merging the directory name (the path) with the filename, I import the module os from the python standard library and use the function os.path.join. This allows writing platform-independent python programs.
To merge the file myfile with the folder name myfolder:
|OS||path and file|
Note that if in this code example the folder
data or the files inside
data are not found, the program will simply leave a message and exit. This is done by using the raise Userwarning command.
import pygame import os try: # load from subfolder 'data' background = pygame.image.load(os.path.join("data","background640x480_a.jpg")) ball = pygame.image.load(os.path.join("data","snake.gif")) except: raise UserWarning, "Unable to find the images in the folder 'data' :-( "
In the big source code example step007.py, you must make sure that the data folder with the needed files is in its place, or the program will produce an error message. Note that the name of the folder is stored in a variable called folder.
import os # .. folder = "data" # replace with "." if pictures lay in the same folder as program prettybackground = pygame.image.load(os.path.join(folder, "800px-La_naissance_de_Venus.jpg"))
Subsurface (Dirty Rect)
Welcome to the wonderful world of cleaning up dirty rects - each frame. The basic idea is to calculate where exactly the screen was “dirty” in the previous frame and calculating a “clean” Subsurface of the original background. Note that the code example below sports a slightly more complicated background than the usual “everything filled with white paint”.
To calculate and blit “dirty rects”, a pygame.subsurface must be created. The syntax is not too hard to understand:
Surface.subsurface(Rect): return Surface
because subsurface returns a surface, it is useful to store this subsurface in a variable like in this code line:
dirtyrect = background.subsurface((x,y,snakerect.width, snakerect.height)) # calculate clean rect screen.blit(dirtyrect, (x,y)) # blit clean rect on top of "dirty" screen
This “clean” subsurface is then blitted on top of the “dirty” part of the screen - on top of the old snake surface, making the whole screen “clean” again. The key is to do that before calculating the new position of the moving snake surface.
If you do not clean the screen, the snake will draw a rather ugly looking trace of its pixel… press D to toggle this effect.
It is more simple to blit the whole background each frame on the screen, like in this out-commented line:
#screen.blit(background, (0,0)) #draw background on screen (overwriting all)
Blitting the whole background on the screen especially makes sense if the background is moving (scrolling). For a static background, you will later learn to use pygame sprites which provide a clean method, freeing you to concentrate on more important stuff than calculating subsurfaces.
Of course you can calculate a subsurface from any surface… as demonstrated in this example with the “tv-screen” in the left top corner. You can also let the snake over-“paint” the ugly background with the pretty background by pressing <key>p</p>.
In this code example, you need to download not only the source code but also download and unzip the data folder (inside step007.tar.gz). The code example will work only if you extract the tar.gz file correctly into the same folder where you downloaded step007.py.
If you did it correctly, you should see your file step007.py and a data folder, containing 3 graphic files:
Source Code on Github
To run this example you need:
|007_loading_files_from_folders_and_subsurfaces.py|| || Download the whole Archive with all files from Github:
| 800px-La_naissance_de_Venus.jpg ||
| background800x470.jpg ||
| snake.gif ||
View/Edit/Download the file directly in Github: https://github.com/horstjens/ThePythonGameBook/blob/master/pygame/007_loading_files_from_folders_and_subsurfaces.py
click reload in your browser if you see no code here: