Warning - This site is moving to https://getthecodingbug.anvil.app
Topics covered
Pygame
Getting started, creating a window
Drawing a rectangle
Detecting events and key-strokes
Loading and moving images around window
Adding sound-effects
Pygame is a Free and Open Source python programming language library for making multimedia applications like games.
Getting started
First, we need to import the pygame library, then initialise pygame, then set a title for your game window.
Next set-up a screen object with dimensions of 800 x 500 pixels.
Finally display your screen.
Create a sub-folder called 'lesson7' under your 'Python_Course' folder for all the following files.
Copy and paste this code into a new python file in your editor, save it as 'pyGame1.py' in the 'lesson7' folder,
then press F5 to run it.
# myPygame1.py
# import the pygame library
import pygame
# initialise pygame pygame.init()
# set a title caption at the top of the window pygame.display.set_caption('My First PyGame')
# set up a screen object with dimensions, width 800 x height 500 pixels screen = pygame.display.set_mode((800, 500))
# Display the screen window pygame.display.flip()
If you run the program from IDLE it should display a black rectangle with your caption at the top, but you have to kill
the python shell, behind it to end the program.
If you ran the program from the command line or via sublime-text, your game window will appear briefly, then disappear and your program will have ended.
This is because the 'pygame.display.flip()' statement needs to be in a loop, to keep your window displayed.
In addition, you need to have a way for the user to exit the display loop to terminate you program properly.
Pygame has a clock function which you can call to maintain a consistent display rate, no matter how fast the computer is.
Copy and paste this code into a new python file in your editor, save it as 'pyGame2.py' and press F5 to run it.
# myPygame2.py
import pygame pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500))
# use the pygame clock clock = pygame.time.Clock()
# establish a display loop, which will run until 'done' is set to 'True' done = False while not done: for event in pygame.event.get():
# check if the user has clicked to top-right 'X' to close the window if event.type == pygame.QUIT: done = True
# keep refreshing the display
pygame.display.flip()
# keep the clock updated clock.tick(60)
# we have exited the display loop now, so terminate pygame pygame.quit()
This time the window should stay until you click to top-right, window close button.
Drawing a rectangle
A black window is not very exciting, but we have to walk before we can run. You can also use this as a basic template for all your future pygame programs. You can change the window title, and screen dimensions and you will also be able to change the background from black to any other colour or an image of your choice.
Next we will create a small green rectangle.
Copy and paste this code into a new python file in your editor, save it as 'pyGame3.py' and press F5 to run it.
# myPygame3.py import pygame pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500)) clock = pygame.time.Clock() # set a colour for our rectangle green = (0, 255, 0) # RGB (i.e. No Red, maximum Green and no Blue component) done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Draw a green rectangle starting at 0, 0, the top-left of the screen # with a width and height of 30 pixels pygame.draw.rect(screen, green, pygame.Rect(0, 0, 30, 30)) pygame.display.flip() clock.tick(60) pygame.quit()
Detecting events and key-strokes
We have already seen that pygame can detect events like the user clicking the close window button. It can also detect other keystrokes, using the 'pygame.key.get_pressed()' function.
We are going to enable the user to move our green rectangle around the screen using the arrow keys on the keyboard.
Copy and paste this code into a new python file in your editor, save it as 'pyGame4.py' and press F5 to run it.
# myPygame4.py import pygame pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500)) clock = pygame.time.Clock() green = (0, 255, 0) # set a colour for our rectangle
# set initial x,y coordinates for our green rectangle x = 0 # left side of screen y = 0 # top side of screen done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Check for keys pressed pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: y -= 3 if pressed[pygame.K_DOWN]: y += 3 if pressed[pygame.K_LEFT]: x -= 3 if pressed[pygame.K_RIGHT]: x += 3 if pressed[pygame.K_q]: done = True # q key # Draw a green rectangle starting at 0, 0, the top-left of the screen # with a width and height of 30 pixels pygame.draw.rect(screen, green, pygame.Rect(x, y, 30, 30)) pygame.display.flip() clock.tick(60) pygame.quit()
You should notice that you can also terminate your program by pressing 'q' key now.
Try pressing the arrow keys and notice what happens to the green rectangle.
It should move around your screen - but it seems to be leaving a trail of green wherever it goes.
We can prevent this trail by clearing out the display each time round the display loop.
You can clear the display to black or any other colour, here I have chosen white.
Add these two lines:
# clear screen screen.fill((255, 255, 255)) # colour = white
before the ' # Draw a green rectangle ...' comment, also make sure they are indented four spaces.
Now when you run the program, the background is white and the green rectangle leaves no trail when it moves.
Loading and moving images around
Pygame also allows us to load images and move them around the screen.
I have created a 64 x 64 pixel image of a tank, using a free image editor, Paint.net, which you can download on your own computer from: https://www.getpaint.net/index.html
When you make your own images, you need to make the image have a transparent background, before saving it with the extension '.png'.
If you don't make it transparent, its background, whatever colour, will move around with the tank, spoiling the effect.
Use the mouse, Right-click the image of the tank below, and choose 'Save image as'
and save the file in the same folder as your Python 'lesson7' files. It should have the name: 'tank_east.png'
The code below is based on 'myPygame4.py' but instead of drawing a green rectangle, it will now display a small tank, pointing eastwards, which you can move around using the arrow keys. Notice the code loads the image, 'tank_east.png', which you should have saved, as directed above, in the same folder as your code.
The statement 'screen.blit(tankimage, (x, y))' displays the tank on the screen, at the current coordinates.
Copy and paste this code into a new python file in your editor, save it as 'pyGame5.py' and press F5 to run it.
# myPygame5.py import pygame pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500)) clock = pygame.time.Clock() green = (0, 255, 0) # set a colour for our rectangle # set initial x,y coordinates for our tank x = 40 y = 40 # Define tank variables tank = 'tank_east.png' # Load tank image tankimage = pygame.image.load(tank) # Draw tank screen.blit(tankimage, (x, y)) done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Check for keys pressed pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: y -= 3 if pressed[pygame.K_DOWN]: y += 3 if pressed[pygame.K_LEFT]: x -= 3 if pressed[pygame.K_RIGHT]: x += 3 if pressed[pygame.K_q]: done = True # q key # clear screen screen.fill((255, 255, 255)) # colour = white # Draw Tank screen.blit(tankimage, (x, y)) pygame.display.flip() clock.tick(60) pygame.quit()
The only problem is that the tank always points East. We can add three more images, so that you can display the tank, pointing, West, North and South as well.
Right-click the three images below and use 'save image as' 'tank_west.png', 'tank_north.png' and 'tank_south.png' in the same folder as 'tank_east.png'.
tank_west.png
tank_north.png
tank_south.png
The code below is based on 'myPygame5.py' but we have added a function to load all four images in a dictionary, for fast and easy loading. Now when you change direction, the appropriate image is loaded so the tank is always pointing in the correct direction.
Copy and paste this code into a new python file in your editor, save it as 'pyGame5.py' and press F5 to run it.
# myPygame6.py import pygame import os # Define Functions _image_library = {} def get_image(path): global _image_library image = _image_library.get(path) if image == None: canonicalized_path = path.replace('/', os.sep).replace('\\', os.sep) image = pygame.image.load(canonicalized_path) _image_library[path] = image return image pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500)) clock = pygame.time.Clock() green = (0, 255, 0) # set a colour for our rectangle # set initial x,y coordinates for our tank x = 40 y = 40 # Define tank variables tank = ['tank_east.png', 'tank_south.png', 'tank_west.png', 'tank_north.png'] EAST = 0 # Indexes for above tank orientations SOUTH = 1 WEST = 2 NORTH = 3 # Draw tank tankdir = EAST screen.blit(get_image(tank[tankdir]), (x, y)) done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Check for keys pressed pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: y -= 3 tankdir = NORTH if pressed[pygame.K_DOWN]: y += 3 tankdir = SOUTH if pressed[pygame.K_LEFT]: x -= 3 tankdir = WEST if pressed[pygame.K_RIGHT]: x += 3 tankdir = EAST if pressed[pygame.K_q]: done = True # q key # clear screen screen.fill((255, 255, 255)) # colour = white # Draw Tank screen.blit(get_image(tank[tankdir]), (x, y)) pygame.display.flip() clock.tick(60) pygame.quit()
We can now make the background a bit more interesting. Right-click the image below and use 'save image as' to save it as 'tank_ground.png' in the same folder as you tank images.
Then copy the 3 lines in the box below and paste them just above the comment:
# set initial x,y coordinates for our tank
# Display background image # set initial x,y coordinates for our tank bg = pygame.image.load("tank_ground.png") bg = pygame.transform.scale(bg, (800, 500)) # stretch to fill window
# clear screen screen.fill((255, 255, 255)) # colour = white
# Re-draw the background screen.blit(bg, (0, 0))
With these two lines, keeping the indentation - 4 spaces, at the start of the line:
Then replace these two lines:
Finally, run your program and you should have a different background.
Adding sound-effects
Now we can add shells which the tank can fire.
Here is a tank shell, shown a bit larger than it really is, please Right-Click, select 'Save image as' and save it as 'shellredblack.png' in the same folder as before.
The next image is for the background, please Right-Click, select 'Save image as' and save it as 'tank_ground.png' in the same folder as before.
Copy and paste this code into a new python file in your editor, save it as 'pyGame8.py' and press F5 to run it.
# myPygame8.py import pygame import os # Define Functions _image_library = {} def get_image(path): global _image_library image = _image_library.get(path) if image == None: canonicalized_path = path.replace('/', os.sep).replace('\\', os.sep) image = pygame.image.load(canonicalized_path) _image_library[path] = image return image pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500)) clock = pygame.time.Clock() green = (0, 255, 0) # set a colour for our rectangle # Display background image bg = pygame.image.load("tank_ground.png") bg = pygame.transform.scale(bg, (800, 500)) # stretch to fill window # set initial x,y coordinates for our tank x = 40 y = 40 # Define tank variables tank = ['tank_east.png', 'tank_south.png', 'tank_west.png', 'tank_north.png'] EAST = 0 # Indexes for above tank orientations SOUTH = 1 WEST = 2 NORTH = 3 # Draw tank tankdir = EAST screen.blit(get_image(tank[tankdir]), (x, y)) # Define Shell variables shx = 0 # Coordinates shy = 0 shoffsetx = 31 # Offset to tank position shoffsety = 31 shdir = EAST # Initial direction shlive = False # Current state shdist = 0 # How far it has travelled shlimit = 150 # Maximum distance of travel shspeed = 4 # Speed of travel done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Check for keys pressed pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: y -= 3 tankdir = NORTH if pressed[pygame.K_DOWN]: y += 3 tankdir = SOUTH if pressed[pygame.K_LEFT]: x -= 3 tankdir = WEST if pressed[pygame.K_RIGHT]: x += 3 tankdir = EAST if pressed[pygame.K_SPACE]: # Fire key if shlive == False: shdir = tankdir shx = x + shoffsetx shy = y + shoffsety shlive = True shdist = 0 if pressed[pygame.K_q]: done = True # q key # Re-draw the background screen.blit(bg, (0, 0)) # Draw Shell (if still live) if (shlive): if shdist < shlimit: shdist += 1 if shdir == NORTH: shy = shy - shspeed if shdir == SOUTH: shy = shy + shspeed if shdir == WEST: shx = shx - shspeed if shdir == EAST: shx = shx + shspeed screen.blit(get_image('shellredblack.png'), (shx, shy)) else: shlive = False # Draw Tank screen.blit(get_image(tank[tankdir]), (x, y)) pygame.display.flip() clock.tick(60) pygame.quit()
Now press the space-bar and you tank should fire a shell.
But we need some sound-effects to make this more realistic.
There are many websites like this one https://freesound.org
where you can download free sound clips, like the one I used below for the sound of the shell being fired.
It is best to use the sound clips that have been created with the extension '.wav'
Next, you need to download the sound-effect file for the shell being fired.
When you click the 'tank-file.wav' link, below, if you are using the Chrome browser, you should see the image below in the centre of the screen - click on the right-hand down arrow to download the file and save it as 'tank-fire.wav' in the same folder as your tank scripts.
Note, other browsers may have a different way to display this and may not give you the option to download.
Here is the link:
The code to handle the sounds is in two parts, first to initialise the sound mixer and load the .wav file.
Then later in the code when the space-bar is detected, 'gunshot.play() '
# Initialise Sounds pygame.mixer.init() gunshot = pygame.mixer.Sound("tank-fire.wav")
gunshot.play()
Finally, to hear the sounds, copy and paste this code into a new python file in your editor,
save it as 'pyGame9.py' and press F5 to run it.
# myPygame9.py import pygame import os # Define Functions _image_library = {} def get_image(path): global _image_library image = _image_library.get(path) if image == None: canonicalized_path = path.replace('/', os.sep).replace('\\', os.sep) image = pygame.image.load(canonicalized_path) _image_library[path] = image return image pygame.init() pygame.display.set_caption('My First PyGame') screen = pygame.display.set_mode((800, 500)) clock = pygame.time.Clock() green = (0, 255, 0) # set a colour for our rectangle # Display background image bg = pygame.image.load("tank_ground.png") bg = pygame.transform.scale(bg, (800, 500)) # stretch to fill window # Initialise Sounds pygame.mixer.init() gunshot = pygame.mixer.Sound("tank-fire.wav") # set initial x,y coordinates for our tank x = 40 y = 40 # Define tank variables tank = ['tank_east.png', 'tank_south.png', 'tank_west.png', 'tank_north.png'] EAST = 0 # Indexes for above tank orientations SOUTH = 1 WEST = 2 NORTH = 3 # Draw tank tankdir = EAST screen.blit(get_image(tank[tankdir]), (x, y)) # Define Shell variables shx = 0 # Coordinates shy = 0 shoffsetx = 31 # Offset to tank position shoffsety = 31 shdir = EAST # Initial direction shlive = False # Current state shdist = 0 # How far it has travelled shlimit = 150 # Maximum distance of travel shspeed = 4 # Speed of travel done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Check for keys pressed pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: y -= 3 tankdir = NORTH if pressed[pygame.K_DOWN]: y += 3 tankdir = SOUTH if pressed[pygame.K_LEFT]: x -= 3 tankdir = WEST if pressed[pygame.K_RIGHT]: x += 3 tankdir = EAST if pressed[pygame.K_SPACE]: # Fire key if shlive == False: shdir = tankdir shx = x + shoffsetx shy = y + shoffsety shlive = True shdist = 0 gunshot.play() if pressed[pygame.K_q]: done = True # q key # Re-draw the background screen.blit(bg, (0, 0)) # Draw Shell (if still live) if (shlive): if shdist < shlimit: shdist += 1 if shdir == NORTH: shy = shy - shspeed if shdir == SOUTH: shy = shy + shspeed if shdir == WEST: shx = shx - shspeed if shdir == EAST: shx = shx + shspeed screen.blit(get_image('shellredblack.png'), (shx, shy)) else: shlive = False # Draw Tank screen.blit(get_image(tank[tankdir]), (x, y)) pygame.display.flip() clock.tick(60) pygame.quit()
Press F5 to run the script and check the sound-effect when the tank fires shells, as the space-bar is pressed.
If you do not hear a sound, check that the speaker is not muted.
What next?
Its up to you, I am sure you can think of many improvements, here are a few ideas:
You could add some targets for the shells to hit.
Make an image of an explosion, as the shell hits the target.
Add a sound-effect for the explosion.
Score points for a direct hit.
Add another tank, with different keys for its movement, so two players can play on the same keyboard.
Have a look at this series of You-Tube videos about developing another game using Pygame :