Jane Rabbit
Jane Rabbit

Reputation: 11

UnboundLocalError: local variable 'event' referenced before assignment [PYGAME]

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

Answers (1)

user2314737
user2314737

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

Related Questions