In this lab you will work through a set of problems involving python objects and classes.
The initial setup involves copying five programs and three image files from the instructor's account to your own, and making each of the programs executable.
Once that is complete, you will be conducting several experiments with the programs and writing a short analysis explaining their behaviour. (All the details are provided below.)
cd games mkdir lab6 cd lab6Next, copy across some files for this week's lab: backdrop.gif , part1a.py , part1b.py, star.gif , part2a.py , part2b.py, ship.gif , part3.py.
Run the ls command and check to see that all eight files are present in your current directory.
Run the chmod command to make the programs executable:
chmod u+x *.py
This completes the setup, you can now proceed to the three key parts of the lab below
Your objective for this part of the exercise is to run the two programs, write the output each produces in the table below, and then explain why they differ the way they do based on the code and the output.
| part1a.py | part1b.py |
#! /usr/bin/python print "progress check A" lives = 3 while (lives > 0): print "lives left: ", lives lives = lives - 1 print "progress check B" |
#! /usr/bin/python
print "progress check A"
def mainGame(numLives):
lives = numLives
while (lives > 0):
print "lives left: ", lives
lives = lives - 1
print "progress check B"
mainGame(4)
print "progress check C"
mainGame(2)
print "progress check D"
|
Output from part1a.py | Output from part1b.py |
Explanation of the difference in output between 1a and 1b | |
Your objective for this part of the exercise is to run the two programs, write the output each produces in the table below, and then explain what advantages, from a coding perspective, part b might have over part a.
| part2a.py | part2b.py |
#! /usr/bin/python # create two critters, specify their name and age bobsName = 'Bob' bobsAge = 5 philsName = 'Phil' philsAge = 1 # run the update routine on each once every 'year' year = 1 while (year <= 3): print "It is year", year bobsAge = bobsAge + 1 philsAge = philsAge + 1 print bobsName, "is now", bobsAge print philsName, "is now", philsAge year = year + 1 |
#! /usr/bin/python
class Critter:
# this routine gets run automatically
# when a Critter is first created
def __init__(self, age, name):
# store the critter's name and age
self.myAge = age
self.myName = name
# this routine ages the critter by a year
def update(self):
self.myAge = self.myAge + 1
print self.myName, "is now", self.myAge
# create a couple of Critters using the class
bob = Critter(5, 'Bob') # bob starts off at age 5
phil = Critter(1, 'Phil') # phil starts off at age 1
# run the update routine on each once every 'year'
year = 1
while (year <= 3):
print "It is year", year
bob.update()
phil.update()
year = year + 1
|
Output from part2a.py | Output from part2b.py |
Possible coding advantages of 2b over 2a | |
Your objectives for this part of the exercise are to:
| part3.py code |
#! /usr/bin/python
# ---------------------------------------------------------------------
# **** LIBRARY SELECTION AND GLOBAL VARIABLE SETUP ****
# ---------------------------------------------------------------------
# import and initialize the pygame module
import pygame
# set up default values for the screen sizes
# (these can be overriden by the setup_pygame function)
screenSize = screenWidth,screenHeight = 480,320
# set up a default display and background image for the game
gameDisplay = None
background = None
# ---------------------------------------------------------------------
# **** PYGAME/DISPLAY SETUP ROUTINE ****
# ---------------------------------------------------------------------
def setup_pygame(width, height):
# make sure we use the global (shared) versions
# of the various screen size variables
global screenSize, screenWidth, screenHeight
global gameDisplay, background
# initialize pygame and the display values
pygame.init()
screenSize = screenWidth,screenHeight = width,height
gameDisplay = pygame.display.set_mode(screenSize)
# load the background image
background = pygame.image.load("backdrop.gif")
# ---------------------------------------------------------------------
# **** CLASS TO DEFINE AND CONTROL OBJECTS THAT MOVE IN THE GAME ****
# ---------------------------------------------------------------------
class movingItem:
def __init__(self, imageFile, (x,y)):
# load the original image from a file
self.Original = pygame.image.load(imageFile)
# set up the initial facing of the item and rotate
# its image to face that direction
self.Facing = 0
self.Image = pygame.transform.rotate(self.Original, self.Facing)
# set up a box (rectangle) around the item
self.Box = self.Image.get_rect()
# set up the initial coordinates for the item
self.Box.x = x
self.Box.y = y
# set the speed so the item is initially stationary
self.Speed = [0,0]
def update(self):
# adjust the object's position based on its current speed
self.Box = self.Box.move(self.Speed)
# have the object 'wrap around' if it goes off the screen
if self.Box.left > screenWidth:
self.Box.right = 1
elif self.Box.right < 0:
self.Box.left = screenWidth - 1
if self.Box.bottom < 0:
self.Box.top = screenHeight - 1
elif self.Box.top > screenHeight:
self.Box.bottom = 1
# rotate the object appropriately for its current facing
self.Image = pygame.transform.rotate(self.Original, self.Facing)
# ---------------------------------------------------------------------
# **** COLLISION HANDLING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine handles collisions between two movingItem objects
def handleCollision(item1, item2):
red = 255,0,0
if (item1.Box.colliderect(item2.Box)):
pygame.draw.line(gameDisplay, red, (0, 0), (screenWidth, screenHeight), 5)
pygame.draw.line(gameDisplay, red, (0, screenHeight), (screenWidth, 0), 5)
pygame.display.flip()
pygame.time.delay(1000)
# ---------------------------------------------------------------------
# **** DISPLAY UPDATING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine handles updating and redrawing the display,
# assuming it is given the background image and a list
# of movingItems to update
def updateDisplay(bck, itemList):
# remember to look up the global display variable
global gameDisplay
# redraw the background picture to the screen buffer
gameDisplay.blit(background, (0,0))
# redraw the items in the order they appear in the list
for i in itemList:
gameDisplay.blit(i.Image, i.Box)
# update the visible display from the screen buffer
pygame.display.flip()
# ---------------------------------------------------------------------
# **** EVENT PROCESSING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine handles all event processing for the game
# it assumes it is given two movingItems to manipulate,
# the first one jumps when the player clicks on the display,
# the second one's speed is controlled by the arrow keys
def handleEvents(jumpingItem, travelingItem):
# check for all events that have taken place during
# this turn (keypresses, mouseclicks, etc)
# and process them one at a time
for event in pygame.event.get():
# check to see if the player clicked the window close box
if event.type == pygame.QUIT:
keepPlaying = False
print "Player command: close window"
# if the player clicked on the screen
# have the star "jump" to the new location
if event.type == pygame.MOUSEBUTTONDOWN:
jumpingItem.Box.center = event.pos
# check to see if the player pressed any keys
if event.type == pygame.KEYDOWN:
# treat the Q key as a quit command
if event.key == pygame.K_q:
print "Player command: quit (q)"
return False
elif event.key == pygame.K_UP:
travelingItem.Speed = [0, -4]
travelingItem.Facing = 45
elif event.key == pygame.K_DOWN:
travelingItem.Speed = [0, 4]
travelingItem.Facing = 225
elif event.key == pygame.K_LEFT:
travelingItem.Speed = [-4, 0]
travelingItem.Facing = 135
elif event.key == pygame.K_RIGHT:
travelingItem.Speed = [4, 0]
travelingItem.Facing = 315
# end of the events for loop
# none of the events said to quit, so return True
return True
# ---------------------------------------------------------------------
# **** MAIN CONTROL/PROCESSING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine controls the operational portion of the game,
# assuming the pygame setup routine has already been run
def mainGame():
# create the moving star and ship
star = movingItem('star.gif', (100,100))
ship = movingItem('ship.gif', (200,200))
# run the game loop
keepPlaying = True
numCollisions = 0
while keepPlaying:
# update the facing, speed, and position of
# the star and the ship
ship.update()
star.update()
# check for collisions between the star and the ship
handleCollision(star, ship)
# redraw the display
updateDisplay(background, [star, ship])
# pause for 20 milliseconds before continuing
pygame.time.delay(30)
# handle any pending events
keepPlaying = handleEvents(star, ship)
# end of the keepPlaying while loop
# ---------------------------------------------------------------------
# **** RUN THE SETUP AND MAIN GAME ROUTINES ***
# ---------------------------------------------------------------------
setup_pygame(640,480)
mainGame()
print "shutting down the game"
# ---------------------------------------------------------------------
# **** END OF PROGRAM ****
# ---------------------------------------------------------------------
|
Description of ship/star control and behaviour |
Explanation of the event sequence |