First, as always, move into your games directory, create a directory for this week's lab, and move into that. E.g.
cd games mkdir lab3 cd lab3Next, copy across some files for this week's lab (right click and 'save as' to the appropriate folder) bck_ocean.gif, star.gif, and game2.py)
The game2.py file is a (slightly cleaned up) version of last week's lab, with the addition of a background image instead of the flat black screen.
Run the chmod command to make the program executable, then try running the game to make sure it works, i.e.:
chmod u+x game2.py ./game2.py
Take a moment to review the code before progressing with the rest of the lab:
#! /usr/bin/python # import and initialize the pygame module import pygame pygame.init() # print an initialization message on the control console print "Starting game console" # set our desired screen width and height (in pixels) screenSize = screenWidth,screenHeight = 400,320 # open a display window of the specified size display = pygame.display.set_mode(screenSize) # load images for the display background and the moving star background = pygame.image.load("bck_ocean.gif") starImage = pygame.image.load("star.gif") # set up a box to track the position of the star starBox = starImage.get_rect() # establish an initial speed for the star [horizontal, vertical] starSpeed = [4,4] # each turn moves 4 pixels right, 4 pixels down # the keepPlaying variable allows us to continue playing # as long as it is set to True keepPlaying = True while keepPlaying: # start of the keepPlaying while loop # adjust the position of the star's containing "box" # based on its current speed starBox = starBox.move(starSpeed) # if the star goes off the left or right edge # reverse its horizontal speed if starBox.left < 0 or starBox.right > screenWidth: starSpeed[0] = - starSpeed[0] print "Bounced: new speed", starSpeed # Note that [0] refers to the first thing in the speed list # while [1] refers to the first thing in the speed list # if the star goes off the top or bottom edge # reverse its vertical speed if starBox.top < 0 or starBox.bottom > screenHeight: starSpeed[1] = - starSpeed[1] print "Bounced: new speed", starSpeed # redraw the background picture to the screen buffer display.blit(background, (0,0)) # redraw the star (in its new position) to the screen buffer display.blit(starImage, starBox) # update the visible display from the screen buffer pygame.display.flip() # pause for 40 milliseconds before continuing pygame.time.delay(40) # check for any events that have taken place during # this turn (keypresses, mouseclicks, etc) for event in pygame.event.get(): # start of the events for loop # check to see if the player clicked the window close box if event.type == pygame.QUIT: keepPlaying = False print "Player command: close window" # end of the events for loop # end of the keepPlaying while loop # print a termination message on the control console print "shutting down the game" |
This time, we'll use its starBox container to place it in the center of the window.
starBox (and any bounding box created using the get_rect() routine) has a variety of properties that tell us where it is currently located and allow us to set a new location:
# starBox.x the star's horizontal position in the window # starBox.y the star's vertical position in the window # starBox.left the position of the star's left edge # starBox.right the position of the star's right edge # starBox.top the position of the star's top edge # starBox.bottom the position of the star's lower edgeIf we want the star to begin in the middle of the window, we can calculate where the middle is (from the width and height of the window) then set the starBox x and y coordinates:
starBox.x = screenWidth / 2 starBox.y = screenHeight / 2Try adding that code to game2.py just after the starBox is created. I.e. just under the line
Try running ./game2.py to see if it has been correctly positioned.
Next, try altering the initial screenSize and see if it still places the star in the center of the screen correctly.
The event processing is handled with a for loop, which basically says
for each event that is ready ... do this to check/process it ...The actual code for the loop currently looks like:
for event in pygame.event.get(): if event.type == pygame.QUIT: keepPlaying = False print "Player command: close window"This simply checks to see if the user has clicked the close X in the upper right corner of the window, setting variable keepPlaying to False if they have.
Then, the next time we get to the start of the while keepPlaying: loop it will realize it's time to stop playing and will bypass the loop.
What we will add now are two more ways for the player to quit: either by hitting the escape key or by pressing the letter q on the keyboard.
Each time a player presses a key on the keyboard it generates a KEYDOWN event, and stores which specific key they pressed as extra information.
We will simply look for any KEYDOWN events, and see if the pressed key was the q or the escape key, e.g.
# check to see if the player pressed any keys if event.type == pygame.KEYDOWN: # treat the Q and escape keys as quit commands if event.key == pygame.K_q: keepPlaying = False print "Player command: quit (q)" elif event.key == pygame.K_ESCAPE: keepPlaying = False print "Player command: quit (escape)"Add that code to the bottom of the for loop, save the file, and try running the game.
See if it allows you to quit simply by pressing escape.
If that works, see if it allows you to quit simply by pressing the letter q.
If the player presses the right arrow we'll add 1 to the horizontal speed, whereas if they press the left arrow we'll subtract 1.
Similarly, if the player presses the down arrow we'll add 1 to the vertical speed, whereas if they press the up arrow we'll subtract 1.
Remember that speeds are stored as a list (e.g. [4,3]) where the first element is the horizontal speed and the second is the vertical.
As an example, to increment the horizontal speed we can use
starSpeed[0] = starSpeed[0] + 1
(The [0] refers to the thing in the first position in the list.)
Now we need to detect when the player has pressed an arrow, i.e. more things to check in our KEYDOWN section.
First, let's just try the right arrow key, adding this just before
or just after our tests for 'q' and
Once that works, try adding the code for the rest of the arrow keys:
The sections below provide a short collection of resources on
finding or creating images, sound effects, and music for your games.
GIMP and image editing
GIMP is freely available from gimp.org,
and a wide variety of tutorials are available. Many decent
gimp tutorials are linked here.
In particular, you might begin with the
guide from minihowto.org . (This is clearer than most, and
provides decent screenshots.)
From there, you might check out the
guides on YouTube,
or start working through some of the core tutorials at gimp.org:
Image resources
As we discussed in class, creation of the images needed for a game
is incredibly time consuming. For small, do-it-yourself projects it
is often more effect to find community resources (and check to make
sure you have the rights to use those resources of course).
Many sites host resource collections, a few examples are linked below.
Sound resources
As with the image resources, creating all the sound effects needed for
a game is another time consuming process. Again, there are community
resources available for use (again, with the proviso that you check
first to ensure you have the rights to use them):
While we will not explicitly go over it in 171, there is a freely available
sound editor: Audacity, with a number of decent tutorials:
# if the player pressed a right arrow then
# adjust the horizontal speed
if event.key == pygame.K_RIGHT:
starSpeed[0] = starSpeed[0] + 1
print "Player command: increase rightward speed", starSpeed
Save and try running the game, hitting the right arrow key a bunch
of times to see if it is picking up speed.
# if the player pressed an arrow key then adjust
# the horizontal or vertical speed
if event.key == pygame.K_RIGHT:
starSpeed[0] = starSpeed[0] + 1
print "Player command: increase rightward speed", starSpeed
elif event.key == pygame.K_LEFT:
starSpeed[0] = starSpeed[0] - 1
print "Player command: decrease rightward speed", starSpeed
elif event.key == pygame.K_UP:
starSpeed[1] = starSpeed[1] - 1
print "Player command: decrease falling speed", starSpeed
elif event.key == pygame.K_DOWN:
starSpeed[1] = starSpeed[1] + 1
print "Player command: increase falling speed", starSpeed
Again, save and run the game and see if you can control the
speed of the star successfully.
Wrap up
The final completed lab should look something like this,
with the key new work highlighted:
#! /usr/bin/python
# import and initialize the pygame module
import pygame
pygame.init()
# print an initialization message on the control console
print "Starting game console"
# set our desired screen width and height (in pixels)
screenSize = screenWidth,screenHeight = 400,320
# open a display window of the specified size
display = pygame.display.set_mode(screenSize)
# load images for the display background and the moving star
background = pygame.image.load("bck_ocean.gif")
starImage = pygame.image.load("star.gif")
# set up a box to track the position of the star
starBox = starImage.get_rect()
# start the star out in the center of the screen
# by setting its x,y coordinates
starBox.x = screenWidth / 2
starBox.y = screenHeight / 2
# establish an initial speed for the star [horizontal, vertical]
starSpeed = [4,4] # each turn moves 4 pixels right, 4 pixels down
# the keepPlaying variable allows us to continue playing
# as long as it is set to True
keepPlaying = True
while keepPlaying:
# start of the keepPlaying while loop
# adjust the position of the star's containing "box"
# based on its current speed
starBox = starBox.move(starSpeed)
# if the star goes off the left or right edge
# reverse its horizontal speed
if starBox.left < 0 or starBox.right > screenWidth:
starSpeed[0] = - starSpeed[0]
print "Bounced: new speed", starSpeed
# Note that [0] refers to the first thing in the speed list
# while [1] refers to the first thing in the speed list
# if the star goes off the top or bottom edge
# reverse its vertical speed
if starBox.top < 0 or starBox.bottom > screenHeight:
starSpeed[1] = - starSpeed[1]
print "Bounced: new speed", starSpeed
# redraw the background picture to the screen buffer
display.blit(background, (0,0))
# redraw the star (in its new position) to the screen buffer
display.blit(starImage, starBox)
# update the visible display from the screen buffer
pygame.display.flip()
# pause for 50 milliseconds before continuing
pygame.time.delay(50)
# check for any events that have taken place during
# this turn (keypresses, mouseclicks, etc)
for event in pygame.event.get():
# start of the events for loop
# check to see if the player clicked the window close box
if event.type == pygame.QUIT:
keepPlaying = False
print "Player command: close window"
# check to see if the player pressed any keys
if event.type == pygame.KEYDOWN:
# if the player pressed an arrow key then adjust
# the horizontal or vertical speed
if event.key == pygame.K_RIGHT:
starSpeed[0] = starSpeed[0] + 1
print "Player command: increase rightward speed", starSpeed
elif event.key == pygame.K_LEFT:
starSpeed[0] = starSpeed[0] - 1
print "Player command: decrease rightward speed", starSpeed
elif event.key == pygame.K_UP:
starSpeed[1] = starSpeed[1] - 1
print "Player command: decrease falling speed", starSpeed
elif event.key == pygame.K_DOWN:
starSpeed[1] = starSpeed[1] + 1
print "Player command: increase falling speed", starSpeed
# treat the Q and escape keys as quit commands
elif event.key == pygame.K_q:
keepPlaying = False
print "Player command: quit (q)"
elif event.key == pygame.K_ESCAPE:
keepPlaying = False
print "Player command: quit (escape)"
# end of the events for loop
# end of the keepPlaying while loop
# print a termination message on the control console
print "shutting down the game"
Part II: image and sound creation and resources
The remainder of the lab is an opportunity to examine some of the
tools and resources available for the images and sound effects
you may wish to create or use in your games.