Program Arcade GamesWith Python And Pygame
To move beyond the simplistic shapes offered by drawing circles and rectangles, our programs need the ability to work with bitmapped graphics. Bitmapped graphics can be photos or images created and saved from a drawing program.
But graphics aren't enough. Games need sound too! This chapter shows how to put graphics and sound in your game.
The programs we've made so far only involve one file. Now that we are including images and sounds, there are more files that are part of our program. It is easy to get these files mixed up with other programs we are making. The way to keep everything neat and separated out is to put each of these programs into its own folder. Before beginning any project like this, click the “new folder” button and use that new folder as a spot to put all the new files as shown in Figure 12.1.
Need to set a background image for your game? Find an image like Figure 12.2. If you are looking on-line in a web browser, you can usually right-click on an image, and save it onto the computer. Save the image to the folder that we just created for our game.
Make sure you don't use copyrighted images! Using a reverse-image search it will be easy for your instructor to check to see if you did copy it. You are half-way through the class, don't risk failing now.
Any bitmap images used in a game should already be sized for how it should appear on the screen. Don't take a 5000x5000 pixel image from a high-resolution camera and then try to load it into a window only 800x600. Use a graphics program (even MS Paint will work) and resize/crop the image before using it in your Python program.
Loading an image is a simple process and involves only one line of code. There is a lot going on in that one line of code, so the explanation of the line will be broken into three parts. The first version of the our load command will load a file called saturn_family1.jpg. This file must be located in the same directory that the python program is in, or the computer will not find it:
That code may load the image, but we have no way to reference that image and display it! We need a variable set equal to what the load() command returns. In the next version of our load command, we create a new variable named background_image. See below for version two:
background_image = pygame.image.load("saturn_family1.jpg")
Finally, the image needs to be converted to a format Pygame can more easily work with. To do that, we append .convert() to the command to call the convert function. The function .convert() is a method in the Image class. We'll talk more about classes, objects, and methods in Chapter 13.
All images should be loaded using code similar to the line below. Just change the variable name and file name as needed.
background_image = pygame.image.load("saturn_family1.jpg").convert()
Loading the image should be done before the main program loop. While it would be possible to load it in the main program loop, this would cause the program to fetch the image from the disk twenty or so times per second. This is completely unnecessary. It is only necessary to do it once at program start-up.
To display the image use the blit command. This “blits” the image bits to the screen. We've already used this command once before when displaying text onto a game window back in Chapter 5.
The blit command is a method in the screen variable, so we need to start our command by screen.blit. Next, we need to pass the image to blit, and where to blit it. This command should be done inside the loop so the image gets drawn each frame. See below:
This code blit's the image held in background_image to the screen starting at (0,0).
Now we want to load an image and move it around the screen. We will start off with a simple red X. See Figure 12.3. The image for this red X may be downloaded from the book's website, or find a .gif or .png that you like with a white background. Don't use a .jpg.
To load the image we need the same type of command that we used with the background image. In this case, I'm assuming the file is saved as player.png.
player_image = pygame.image.load("player.png").convert()
Inside the main program loop, the mouse coordinates are retrieved, and passed to another blit function as the coordinates to draw the image:
# Get the current mouse position. This returns the position # as a list of two numbers. player_position = pygame.mouse.get_pos() x = player_position y = player_position # Copy image to screen: screen.blit(player_image, [x,y])
This demonstrates a problem. The image is a red X with a white background. So when the image is drawn the program shows Figure 12.4.
We only want the red X, not the white background. But all images we can load are rectangles, so how do we show only the part of the image we want? The way to get around this is to tell the program to make one color “transparent” and not display. This can be done immediately after loading. The following makes the color white (assuming white is already defined as a variable) transparent:
This will work for most files ending in .gif and .png. This does not work well for most .jpg files. The jpeg image format is great for holding photographs, but it does subtly change the image as part of the algorithm that makes the image smaller. This means that not all of the background color will be the same. In Figure 12.5 the X has been saved as a jpeg. The white around the X is not exactly (255, 255, 255), but just really close.
If you are picking out an image that will be transparent, choose a .gif or .png. These are the best formats for graphic art type of images. Photos should be .jpg. Keep in mind it is not possible to change a .jpg to another format just by renaming the file extension to .png. It is still a .jpg even if you call it something different. It requires conversion in a graphics program to change it to a different format. But once in a .jpg format, it has been altered and converting it to a .png won't fix those alterations.
In this section we'll play a clicking sound when the mouse button is clicked.
You can download and save the sound here:
Like images, sounds must be loaded before they are used. This should be done once sometime before the main program loop. The following command loads a sound file and creates a variable named click_sound to reference it:
click_sound = pygame.mixer.Sound("click.wav")
We can play the sound by using the following command:
But where do we put this command? If we put it in the main program loop it will play it twenty times or so per second. Really annoying. We need a “trigger.” Some action occurs, then we play the sound. For example this sound can be played when the user hits the mouse button with the following code:
for event in pygame.event.get(): if event.type == pygame.QUIT: done = True if event.type == pygame.MOUSEBUTTONDOWN: click_sound.play()
Uncompressed sound files usually end in .wav. These files are larger than other formats because no algorithm has been run on them to make them smaller. There is also the ever popular .mp3 format, although that format has patents that can make it undesirable for certain applications. Another format that is free to use is the OGG Vorbis format that ends in .ogg.
Pygame does not play all .wav files that can be found on the Internet. If you have a file that isn't working, you can try using the program Audacity to convert it to an ogg-vorbis type of sound file that ends in .ogg. This file format is small and reliable for use with pygame.
If you want background music to play in your program, then check out the on-line
example section for:
Please note that you can't redistribute copyrighted music with your program. Even if you make a video of your program with copyrighted music in the background YouTube and similar video sights will flag you for copyright violation.
# Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # Explanation video: http://youtu.be/4YqIKncMJNs # Explanation video: http://youtu.be/ONAK8VZIcI4 # Explanation video: http://youtu.be/_6c4o41BIms import pygame # Define some colors white = (255, 255, 255) black = (0, 0, 0) # Call this function so the Pygame library can initialize itself pygame.init() # Create an 800x600 sized screen screen = pygame.display.set_mode([800, 600]) # This sets the name of the window pygame.display.set_caption('CMSC 150 is cool') clock = pygame.time.Clock() # Before the loop, load the sounds: click_sound = pygame.mixer.Sound("click.wav") # Set positions of graphics background_position = [0,0] # Load and set up graphics. background_image = pygame.image.load("saturn_family1.jpg").convert() player_image = pygame.image.load("player.png").convert() player_image.set_colorkey(white) done = False while done == False: clock.tick(10) for event in pygame.event.get(): if event.type == pygame.QUIT: done=True if event.type == pygame.MOUSEBUTTONDOWN: click_sound.play() # Copy image to screen: screen.blit(background_image, background_position) # Get the current mouse position. This returns the position # as a list of two numbers. player_position = pygame.mouse.get_pos() x = player_position y = player_position # Copy image to screen: screen.blit(player_image, [x,y]) pygame.display.flip() pygame.quit ()
For the following file extensions, write the extension next to the item that applies:
- Graphic art
- Uncompressed images
- Songs and sound effects
- Uncompressed sounds
What do the following Python programs print?
def f(): return 10 x = f() print(x)
def f(x): x = x + 10 return x x = 10 f(x) print(x)
def f(x): x = x + 10 return x def g(x): return x * 2 print ( f( g(10) ) )
def f(x): x = x + 10 return x def g(x): return x * 2 print ( g( f(10) ) )
def f(x, y): return x / y x=20 y=5 print ( f(y, x) )
def f(x): return x * 2 def g(x): return x - 2 def h(x): return x + 10 print ( f(5) + g(f(5)) + h(g(10)) ) print ( h(g(f(10))) )
x = len( [2,3,[5,6],[7,9]] ) print(x)
- Write a function that prints “Hello.”
- Call the function in the prior problem.
- Write a function that takes in a string as a parameter and counts the number of spaces in it.
- Write a function that takes in an array as a parameter and prints each element individually.
- Write a function that takes in an array as a parameter and returns the sum.
Complete Lab 7 “Bitmapped Graphics and User Control” to control graphics and sound. You're getting close to creating a game!
You are not logged in. Log in here and track your progress.