Reputation: 11
I am currently trying to create a game for a school assignment setting up timers for some events in one of my levels, but the "UnboundLocalError" keeps appearing and I'm not sure how to fix it. I've read some other posts where you can set the variable as global but I've tried that in a few places and it still gives me the same error. We are using python 3.4.3.
Here is my code:
import pygame
import random
import sys
import time
import os
#Global Colours and Variables
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
DARKGREEN = (0, 155, 0)
DARKGRAY = (40, 40, 40)
BLUE = (23, 176, 199)
WHITE = (255, 255, 255)
WIDTH = 640
HEIGHT = 480
TILE_SIZE = 32
NUM_TILES_WIDTH = WIDTH//TILE_SIZE
NUM_TILES_HEIGHT = HEIGHT//TILE_SIZE
COUNT = 10
COOKIEVENT = pygame.USEREVENT
pygame.time.set_timer(COOKIEVENT, 3000)
REVENT = pygame.USEREVENT + 3
pygame.time.set_timer(REVENT, 5000)
PEVENT = pygame.USEREVENT + 2
pygame.time.set_timer(PEVENT ,5000)
# - level 1 -
MAXHEALTH = 3
SCORE = 0
grave = pygame.sprite.Sprite()
#Global Definitions
candies = pygame.sprite.OrderedUpdates()
def add_candy(candies):
candy = pygame.sprite.Sprite()
candy.image = pygame.image.load('cookie.png')
candy.rect = candy.image.get_rect()
candy.rect.left = random.randint(1, 19)*32
candy.rect.top = random.randint(1, 13)*32
candies.add(candy)
for i in range(10):
add_candy(candies)
# OPENING SCREEN DEFINITIONS
def showStartScreen():
screen.fill((DARKGRAY))
StartFont = pygame.font.SysFont('Browallia New', 20, bold = False, italic = False)
first_image = StartFont.render("Instructions: Eat all the good cookies!", True, (255, 255, 255))
second_image = StartFont.render("Raccoon and purple cookies will kill you!", True, (255, 255, 255))
third_image = StartFont.render("Collect potions to regain HP!", True, (255, 255, 255))
first_rect = first_image.get_rect(centerx=WIDTH/2, centery=100)
second_rect = second_image.get_rect(centerx=WIDTH/2, centery=120)
third_rect = third_image.get_rect(centerx=WIDTH/2, centery=140)
screen.blit(first_image, first_rect)
screen.blit(second_image, second_rect)
screen.blit(third_image, third_rect)
while True:
drawPressKeyMsg()
if checkForKeyPress():
pygame.event.get()
return
pygame.display.update()
def showlevel2StartScreen():
screen.fill((DARKGRAY))
StartFont = pygame.font.SysFont('Browallia New', 20, bold = False, italic = False)
title_image = StartFont.render("Instructions: Eat all the cookies before the timer runs out!", True, (255, 255, 255))
title_rect = title_image.get_rect(centerx=WIDTH/2, centery=100)
screen.blit(title_image, title_rect)
while True:
drawPressKeyMsg()
if checkForKeyPress():
pygame.event.get()
return
pygame.display.update()
def drawPressKeyMsg():
StartFont = pygame.font.SysFont('Browallia New', 20, bold = False, italic = False)
pressKeyScreen = StartFont.render('Press any key to play.', True, WHITE)
pressKeyRect = pressKeyScreen.get_rect(centerx=WIDTH/2, centery=160)
screen.blit(pressKeyScreen, pressKeyRect)
def checkForKeyPress():
if len(pygame.event.get(pygame.QUIT)) > 0:
terminate()
keyUpEvents = pygame.event.get(pygame.KEYUP)
if len(keyUpEvents) == 0:
return None
if keyUpEvents[0] == pygame.K_ESCAPE:
terminate()
return keyUpEvents[0].key
def getRandomLocation():
return {'x': random.randint(0, TILE_SIZE - 1), 'y': random.randint(0, TILE_SIZE - 1)}
def terminate():
pygame.quit()
sys.exit()
# LEVEL 1 DEFINITIONS
pcandies = pygame.sprite.OrderedUpdates()
def add_candie(pcandies):
candy = pygame.sprite.Sprite()
candy.image = pygame.image.load('cookie.png')
candy.rect = candy.image.get_rect()
pcandy = pygame.sprite.Sprite()
pcandy.image = pygame.image.load('pcookie.png')
pcandy.rect = pcandy.image.get_rect()
pcandy.rect.left = random.randint(1, 19)*32
pcandy.rect.top = random.randint(1, 13)*32
candycollides = pygame.sprite.groupcollide(pcandies, candies, False, True)
while len(candycollides) > 0:
pcandies.remove(pcandy)
pcandy.rect.left = random.randint(1, 19)*32
pcandy.rect.top = random.randint(1, 13)*32
pcandies.add(pcandy)
for i in range (5):
add_candie(pcandies)
raccoons = pygame.sprite.GroupSingle()
def add_raccoon(raccoon):
raccoon = pygame.sprite.Sprite()
raccoon.image = pygame.image.load('enemy.gif')
raccoon.rect = raccoon.image.get_rect()
raccoon.rect.left = random.randint(1, 19)*32
raccoon.rect.top = random.randint(1, 13)*32
raccoon.add(raccoons)
potions = pygame.sprite.GroupSingle()
def add_potion(potion):
potion = pygame.sprite.Sprite()
potion.image = pygame.image.load('potion.gif')
potion.rect = potion.image.get_rect()
potion.rect.left = random.randint(1, 20)*32
potion.rect.top = random.randint(1, 13)*32
potion.add(potions)
#Classes
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color):
""" Constructor function """
#Call the parent's constructor
super().__init__()
self.image = pygame.screen([width, height])
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
class Room():
#Each room has a list of walls, and of enemy sprites.
wall_list = None
candies = None
def __init__(self):
self.wall_list = pygame.sprite.Group()
self.candies = pygame.sprite.Group
class Player(pygame.sprite.Sprite):
# Set speed vector
change_x = 0
change_y = 0
def __init__(self, x, y):
super().__init__()
#Setting up main character + Adding image/properties to hero!
player = pygame.sprite.Sprite()
player.image = pygame.image.load('rabbit.png')
player_group = pygame.sprite.GroupSingle(hero)
player.rect = player.image.get_rect()
player.rect.y = y
player.rect.x = x
def changespeed(self, x, y):
""" Change the speed of the player. Called with a keypress. """
player.change_x += x
player.change_y += y
def move(self, walls):
""" Find a new position for the player """
# Move left/right
player.rect.x += player.change_x
# Did this update cause us to hit a wall?
block_hit_list = pygame.sprite.spritecollide(player, walls, False)
for block in block_hit_list:
# If we are moving right, set our right side to the left side of
# the item we hit
if player.change_x > 0:
player.rect.right = block.rect.left
else:
# Otherwise if we are moving left, do the opposite.
player.rect.left = block.rect.right
# Move up/down
player.rect.y += player.change_y
# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if player.change_y > 0:
player.rect.bottom = block.rect.top
else:
player.rect.top = block.rect.bottom
class levelwalls(Room):
def __init__(self):
Room.__init__(self)
#Make the walls. (x_pos, y_pos, width, height)
# This is a list of walls. Each is in the form [x, y, width, height]
walls = [[0, 0, 20, 250, WHITE],
[0, 350, 20, 250, WHITE],
[780, 0, 20, 250, WHITE],
[780, 350, 20, 250, WHITE],
[20, 0, 760, 20, WHITE],
[20, 580, 760, 20, WHITE],
[390, 50, 20, 500, BLUE]
]
# Loop through the list. Create the wall, add it to the list
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
def main():
pygame.init()
global FPSCLOCK, screen, my_font, munch_sound, bunny_sound, potion_sound, COOKIEVENT, PEVENT, REVENT
FPSCLOCK = pygame.time.Clock()
munch_sound = pygame.mixer.Sound('crunch.wav')
bunny_sound = pygame.mixer.Sound('sneeze.wav')
screen = pygame.display.set_mode((WIDTH,HEIGHT))
my_font = pygame.font.SysFont('Browallia New', 34, bold = False, italic = False)
pygame.display.set_caption('GRABBIT')
#Sounds
pygame.mixer.music.load('Music2.mp3')
pygame.mixer.music.play(-1,0.0)
potion_sound = pygame.mixer.Sound('Correct.wav')
COOKIEVENT = pygame.USEREVENT
pygame.time.set_timer(COOKIEVENT, 3000)
REVENT = pygame.USEREVENT + 3
pygame.time.set_timer(REVENT, 5000)
PEVENT = pygame.USEREVENT + 2
pygame.time.set_timer(PEVENT ,5000)
showStartScreen()
while True:
level1_init()
showGameOverScreen
def level1_init():
global COOKIEVENT, PEVENT, REVENT
finish = False
win = False
gameOverMode = False
move = True
MAXHEALTH = 3
SCORE = 0
count = 10
COOKIEVENT = pygame.USEREVENT
pygame.time.set_timer(COOKIEVENT, 3000)
REVENT = pygame.USEREVENT + 3
pygame.time.set_timer(REVENT, 5000)
PEVENT = pygame.USEREVENT + 2
pygame.time.set_timer(PEVENT ,5000)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
terminate()
def drawHealthMeter(currentHealth):
for i in range(currentHealth): # draw health bars
pygame.draw.rect(screen, BLUE, (15, 5 + (10 * MAXHEALTH) - i * 10, 20, 10))
for i in range(MAXHEALTH): # draw the white outlines
pygame.draw.rect(screen, WHITE, (15, 5 + (10 * MAXHEALTH) - i * 10, 20, 10), 1)
if event.type == COOKIEVENT:
if win == False and gameOverMode == False:
add_candy(candies)
if event.type == PEVENT:
if win == False and gameOverMode == False:
add_potion(potions)
if event.type == REVENT:
if win == False and gameOverMode == False:
add_raccoon(raccoons)
if move == True:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
hero.rect.top -= TILE_SIZE
elif event.key == pygame.K_DOWN:
hero.rect.top += TILE_SIZE
elif event.key == pygame.K_RIGHT:
hero.rect.right += TILE_SIZE
elif event.key == pygame.K_LEFT:
hero.rect.right -= TILE_SIZE
elif event.key == pygame.K_ESCAPE:
terminate()
screen.fill((DARKGRAY))
grass = pygame.image.load('grass.jpg')
for x in range(int(WIDTH/grass.get_width()+3)):
for y in range(int(HEIGHT/grass.get_height()+3)):
screen.blit(grass,(x*100,y*100))
candies.draw(screen)
pcandies.draw(screen)
potions.draw(screen)
hero_group.draw(screen)
raccoons.draw(screen)
playerObj = {'health': MAXHEALTH}
drawHealthMeter(playerObj['health'])
#Collision with Raccoon
instantdeath = pygame.sprite.groupcollide(hero_group, raccoons, False, True)
if len(instantdeath) > 0:
bunny_sound.play()
MAXHEALTH = 0
#Health Potions
morehealth = pygame.sprite.groupcollide(hero_group, potions, False, True)
if len(morehealth) > 0:
potion_sound.play()
MAXHEALTH = MAXHEALTH + 1
#Collision with Bad Cookies
bad = pygame.sprite.groupcollide(hero_group, pcandies, False, True)
if len(bad) > 0:
bunny_sound.play()
MAXHEALTH = MAXHEALTH - 1
if playerObj['health'] == 0:
gameOverMode = True
move = False
grave.image = pygame.image.load('grave.png')
grave.rect = grave.image.get_rect(left = hero.rect.left, top = hero.rect.top)
screen.blit(grave.image, grave.rect)
#Collision with Good Cookies
collides = pygame.sprite.groupcollide(hero_group, candies, False, True)
if len(collides) > 0:
munch_sound.play()
SCORE += 1
if len(candies) == 0:
win = True
scoretext = my_font.render("Score = "+str(SCORE), 1, (255, 255, 255))
screen.blit(scoretext, (520, 5))
#If you collide with Racoon
if gameOverMode == True:
font = pygame.font.SysFont('Browallia New', 36, bold = False, italic = False)
text_image = font.render("You Lose. Game Over!", True, (255, 255, 255))
text_rect = text_image.get_rect(centerx=WIDTH/2, centery=100)
screen.blit(text_image, text_rect)
if win:
move = False
CEVENT = pygame.USEREVENT + 5
pygame.time.set_timer(CEVENT, 1000)
if count > 0:
if event.type == CEVENT:
count -= 1
text_image = my_font.render('You won! Next level will begin in ' + str(count) + ' seconds', True, (255, 255, 255))
text_rect = text_image.get_rect(centerx=WIDTH/2, centery=100)
screen.blit(text_image, text_rect)
score_text_image = my_font.render("You achieved a score of " + str(SCORE), True, (255, 255, 255))
score_text_rect = score_text_image.get_rect(centerx = WIDTH/2, centery = 150)
screen.blit(score_text_image, score_text_rect)
if count == 0:
showlevel2StartScreen()
win = False
level2_init()
pygame.display.update()
main()
pygame.quit()
The error comes up as:
Traceback (most recent call last):
File "F:\Year 10\IST\Programming\Pygame\Final Game\Final Game - Grabbit.py", line 426, in <module>
main()
File "F:\Year 10\IST\Programming\Pygame\Final Game\Final Game - Grabbit.py", line 284, in main
level1_init()
File "F:\Year 10\IST\Programming\Pygame\Final Game\Final Game - Grabbit.py", line 324, in level1_init
if event.type == COOKIEVENT:
UnboundLocalError: local variable 'event' referenced before assignment
Is anyone able to suggest what I could do to fix this? Would also appreciate any tips for improvements in my code. I'm a beginner at python and this is the first project I've undertaken using this coding language. Thank you.
Upvotes: 0
Views: 3526
Reputation: 29437
The event
variable is not initialized in the line
if event.type == COOKIEVENT:
You may need to indent that part of the code so that it goes inside the loop
for event in pygame.event.get():
....
if event.type == COOKIEVENT:`
Upvotes: 2