0

I've been trying to make the main menu with my game. But every time I would run it and 'start' the game. it would give me this error

line 303, in redrawGameWindow text = font.render('Score: ' + str(score), 1, (0, 0, 0)) NameError: free variable 'score' referenced before assignment in enclosing scope

Which then I try to fix but couldn't.

Here's the full code:

pygame.init()

win = pygame.display.set_mode((500, 480))

pygame.display.set_caption("First Game")

walkRight = [pygame.image.load('BR1.png'), pygame.image.load('BR2.png'), pygame.image.load('BR3.png'),
             pygame.image.load('BR4.png'), pygame.image.load('BR5.png'), pygame.image.load('BR6.png'),
             pygame.image.load('BR7.png'), pygame.image.load('BR8.png'), pygame.image.load('BR9.png')]
walkLeft = [pygame.image.load('BL1.png'), pygame.image.load('BL2.png'), pygame.image.load('BL3.png'),
            pygame.image.load('BL4.png'), pygame.image.load('BL5.png'), pygame.image.load('BL6.png'),
            pygame.image.load('BL7.png'), pygame.image.load('BL8.png'), pygame.image.load('BL9.png')]

bg = pygame.image.load('bg.png')

char = pygame.image.load('Bstanding.png')

clock = pygame.time.Clock()

bulletSound = pygame.mixer.Sound('bullet.wav')
hitSound = pygame.mixer.Sound('hit.wav')

music = pygame.mixer.music.load('music.wav')
pygame.mixer.music.play(loops=-1)

score = 0

#Variables
darkYellow = 204,204,0
grey = 102, 102, 102
black = 0, 0, 0
white = 255, 255, 255
red = 255,0,0
marroon = 120, 0, 0
green = 0,255,0
blue = 0,0,255
darkBlue = 0,0,128

resolution = 650, 600
myFont = pygame.font.SysFont("Times New Roman", 30)
myFont2 = pygame.font.SysFont("Times New Roman", 15)
myFont3 = pygame.font.SysFont("Times New Roman", 60)

redLeft = 150, 575
redRight = 280, 575
blackLeft = 370, 575
blackRight = 500, 575
radius = 20

def mainMenu():

    rectWidth = 150
    rectHeight = 40

    #Draw buttons
    pygame.draw.rect(window, (white),(250, 150, rectWidth, rectHeight),0)
    pygame.draw.rect(window, (white),(250, 225, rectWidth, rectHeight),0)
    pygame.draw.rect(window, (white),(250, 300, rectWidth, rectHeight),0)
    highlight = pygame.draw.rect(window, (darkYellow),(250, 150, rectWidth,rectHeight),0)
    pygame.display.update()

    playGameText = myFont.render("Play Game", 1, red)
    window.blit(playGameText, (260, 150))
    optionsText = myFont.render("Options", 1, red)
    window.blit(optionsText, (275, 225))
    exitText = myFont.render("Exit", 1, red)
    window.blit(exitText, (300, 300))
    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                game()

def main():
    global window
    window = pygame.display.set_mode(resolution)
    pygame.display.set_caption('Harrys Game')
    mainMenu()

def game():
    while True:
        class player(object):
            def __init__(self, x, y, width, height):
                self.x = x
                self.y = y
                self.width = width
                self.height = height
                self.vel = 5
                self.isJump = False
                self.left = False
                self.right = False
                self.walkCount = 0
                self.jumpCount = 10
                self.standing = True
                self.hitbox = (self.x + 17, self.y + 11, 29, 52)

            def draw(self, win):
                if self.walkCount + 1 >= 27:
                    self.walkCount = 0

                if not (self.standing):
                    if self.left:
                        win.blit(walkLeft[self.walkCount // 3], (self.x, self.y))
                        self.walkCount += 1
                    elif self.right:
                        win.blit(walkRight[self.walkCount // 3], (self.x, self.y))
                        self.walkCount += 1
                else:
                    if self.right:
                        win.blit(walkRight[0], (self.x, self.y))
                    else:
                        win.blit(walkLeft[0], (self.x, self.y))
                self.hitbox = (self.x + 17, self.y + 11, 29, 52)
                # pygame.draw.rect(win, (255,0,0), self.hitbox,2)

            def hit(self):
                self.isJump = False
                self.jumpCount = 10
                self.x = 100
                self.y = 410
                self.walkCount = 0
                font1 = pygame.font.SysFont('comicsans', 100)
                text = font1.render('-5', 1, (255, 0, 0))
                win.blit(text, (250 - (text.get_width() / 2), 200))
                pygame.display.update()
                i = 0
                while i < 200:
                    pygame.time.delay(10)
                    i += 1
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            i = 201
                            pygame.quit()


        class projectile(object):
            def __init__(self, x, y, radius, color, facing):
                self.x = x
                self.y = y
                self.radius = radius
                self.color = color
                self.facing = facing
                self.vel = 8 * facing

            def draw(self, win):
                pygame.draw.circle(win, self.color, (self.x, self.y), self.radius)


        class enemy(object):
            walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'),
                         pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'),
                         pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'),
                         pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
            walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
                        pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
                        pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'),
                        pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]

            def __init__(self, x, y, width, height, end):
                self.x = x
                self.y = y
                self.width = width
                self.height = height
                self.end = end
                self.path = [self.x, self.end]
                self.walkCount = 0
                self.vel = 3
                self.hitbox = (self.x + 17, self.y + 2, 31, 57)
                self.health = 10
                self.visible = True

            def draw(self, win):
                self.move()
                if self.visible:
                    if self.walkCount + 1 >= 33:
                        self.walkCount = 0

                    if self.vel > 0:
                        win.blit(self.walkRight[self.walkCount // 3], (self.x, self.y))
                        self.walkCount += 1
                    else:
                        win.blit(self.walkLeft[self.walkCount // 3], (self.x, self.y))
                        self.walkCount += 1

                    pygame.draw.rect(win, (255, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10))
                    pygame.draw.rect(win, (0, 128, 0), (self.hitbox[0], self.hitbox[1] - 20, 50 - (5 * (10 - self.health)), 10))
                    self.hitbox = (self.x + 17, self.y + 2, 31, 57)
                    # pygame.draw.rect(win, (255,0,0), self.hitbox,2)

            def move(self):
                if self.vel > 0:
                    if self.x + self.vel < self.path[1]:
                        self.x += self.vel
                    else:
                        self.vel = self.vel * -1
                        self.walkCount = 0
                else:
                    if self.x - self.vel > self.path[0]:
                        self.x += self.vel
                    else:
                        self.vel = self.vel * -1
                        self.walkCount = 0

            def hit(self):
                if self.health > 0:
                    self.health -= 1
                else:
                    self.visible = False
                print('hit')

        # mainloop
        font = pygame.font.SysFont('comicsans', 30, True)
        man = player(200, 410, 64, 64)
        goblin = enemy(100, 410, 64, 64, 450)
        shootLoop = 0
        bullets = []
        run = True
        while run:
            clock.tick(27)

            if goblin.visible == True:
                if man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and man.hitbox[1] + man.hitbox[3] > goblin.hitbox[1]:
                    if man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and man.hitbox[0] < goblin.hitbox[0] + goblin.hitbox[2]:
                        man.hit()
                        score -= 5

            if shootLoop > 0:
                shootLoop += 1
            if shootLoop > 3:
                shootLoop = 0

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False

            for bullet in bullets:
                if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[
                    1]:
                    if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + \
                            goblin.hitbox[2]:
                        hitSound.play()
                        goblin.hit()
                        score += 1
                        bullets.pop(bullets.index(bullet))

                if bullet.x < 500 and bullet.x > 0:
                    bullet.x += bullet.vel
                else:
                    bullets.pop(bullets.index(bullet))

            keys = pygame.key.get_pressed()

            if keys[pygame.K_SPACE] and shootLoop == 0:
                bulletSound.play()
                if man.left:
                    facing = -1
                else:
                    facing = 1

                if len(bullets) < 5:
                    bullets.append(
                        projectile(round(man.x + man.width // 2), round(man.y + man.height // 2), 6, (0, 0, 0), facing))

                shootLoop = 1

            if keys[pygame.K_LEFT] and man.x > man.vel:
                man.x -= man.vel
                man.left = True
                man.right = False
                man.standing = False
            elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel:
                man.x += man.vel
                man.right = True
                man.left = False
                man.standing = False
            else:
                man.standing = True
                man.walkCount = 0

            if not (man.isJump):
                if keys[pygame.K_UP]:
                    man.isJump = True
                    man.right = False
                    man.left = False
                    man.walkCount = 0
            else:
                if man.jumpCount >= -10:
                    neg = 1
                    if man.jumpCount < 0:
                        neg = -1
                    man.y -= (man.jumpCount ** 2) * 0.5 * neg
                    man.jumpCount -= 1
                else:
                    man.isJump = False
                    man.jumpCount = 10

            def redrawGameWindow():
                win.blit(bg, (0, 0))
                text = font.render('Score: ' + str(score), 1, (0, 0, 0))
                win.blit(text, (350, 10))
                man.draw(win)
                goblin.draw(win)
                for bullet in bullets:
                    bullet.draw(win)

                pygame.display.update()

            redrawGameWindow()
main()
pygame.quit()

Sorry if it's too long. But the def is more in the top/bottom. I'm just a beginner wanting to learn more.

  • The error message is very clear. Read about the [`global` statement](https://docs.python.org/3/reference/simple_stmts.html?highlight=global#grammar-token-global-stmt) and [Using global variables in a function](https://stackoverflow.com/questions/423379/using-global-variables-in-a-function). Add `global score` to `redrawGameWindow `. – Rabbid76 Jul 24 '22 at 05:33
  • Thank you! I fixed the issue and learned a new thing :) – GjonHut Jul 25 '22 at 18:09

0 Answers0