-1

I have an issue where i need to call some variables in more than one function and can not get them to declare in the game_loop() function. The variables are called outside of the game_loop function but the variables are also being called into other functions. How can I get the variables to call in the game_loop function and all other functions that call them as well?

Please see code below:

            import math
            import random
            
            import pygame
            from pygame import mixer
            
            # Intialize the pygame
            pygame.init()
            
            # next setup the display
            display_width = 800
            display_height = 600
            screen = pygame.display.set_mode((800, 600))
            
            # Background
            background = pygame.image.load('waterbackground.jpg')
            
            # game clock to time frames per second 
            clock = pygame.time.Clock()
            
            # Sound
            mixer.music.load("ocean.wav")
            mixer.music.play(-1)
            
            # setup colors needed in the game
            black = (0,0,0)
            white = (255, 255, 255)
            red = (200, 0, 0)
            bright_red = (255,0,0)
            block_color = (53,115,255)
            green = (0,200,0)
            bright_green = (0,255,0)
            
            # Caption and Icon
            pygame.display.set_caption("Pirate War")
            icon = pygame.image.load('pirateship.png')
            pygame.display.set_icon(icon)
            
            # cannon
            cannonImg = pygame.image.load('cannonball.png')
            cannonX = 0
            cannonY = 480
            cannonX_change = 0
            cannonY_change = 10
            cannon_state = "ready"
                
            
            # Player
            playerImg = pygame.image.load('cannon.png')
            playerX = 370
            playerY = 480
            playerX_change = 0
            
            # Score
            score_value = 0
            
            
            # ship
            shipImg = []
            shipX = []
            shipY = []
            shipX_change = []
            shipY_change = []
            num_of_ships = 6
            
            for i in range(num_of_ships):
                shipImg.append(pygame.image.load('pirateship.png'))
                shipX.append(random.randint(0, 736))
                shipY.append(random.randint(50, 150))
                shipX_change.append(4)
                shipY_change.append(40)
            
            
            font = pygame.font.Font('freesansbold.ttf', 32)
            
            textX = 10
            testY = 10
            
            # Game Over
            over_font = pygame.font.Font('freesansbold.ttf', 64)
            
            # text object function called by message display function
            def text_objects(text, font):
                textSurface = font.render(text, True, black)
                return textSurface, textSurface.get_rect()
            
            
            def show_score(x, y):
                score = font.render("Score : " + str(score_value), True, (255, 255, 255))
                screen.blit(score, (x, y))
            
            
            def game_over_text():
                over_text = over_font.render("GAME OVER", True, (255, 255, 255))
                screen.blit(over_text, (200, 250))
            
            
            def player(x, y):
                screen.blit(playerImg, (x, y))
            
            
            def ship(x, y, i):
                screen.blit(shipImg[i], (x, y))
            
            
            def fire_cannon(x, y):
                global cannon_state
                cannon_state = "fire"
                screen.blit(cannonImg, (x + 16, y + 10))
            
            
            def isCollision(shipX, shipY, cannonX, cannonY):
                distance = math.sqrt(math.pow(shipX - cannonX, 2) + (math.pow(shipY - cannonY, 2)))
                if distance < 27:
                    return True
                else:
                    return False
            
            
            def button(msg, x, y, w, h, ic, ac, action=None): 
                mouse = pygame.mouse.get_pos() # returns a list of [x,y]
                click = pygame.mouse.get_pressed()
                
                if x+w > mouse[0] > x and y+h > mouse[1] > y: #check is mouse over button
                    # redraw the rectange with active color when mouseover
                    pygame.draw.rect(screen, ac, (x, y, w, h))
                    #check for a click
                    if click[0] == 1 and action!=None:
                        action()
                else:
                    pygame.draw.rect(screen, ic, (x, y, w, h))
                # now display text on top of button that was just redrawn
                smallText = pygame.font.Font('freesansbold.ttf', 20)
                TextSurf, TextRect = text_objects(msg, smallText)
                TextRect.center = ((x+(w/2)), (y+(h/2)))
                screen.blit(TextSurf, TextRect)
                
                
            def quitgame():
                pygame.quit()
                quit() 
                
            # start screen code
            def game_intro():
                intro = True
                while intro:
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            pygame.quit()
                            quit()
                    screen.fill((0, 0, 0))
                    # Background Image
                    screen.blit(background, (0, 0))
                    largeText = pygame.font.Font('freesansbold.ttf', 115)
                    TextSurf, TextRect = text_objects("Pirate War", largeText)
                    TextRect.center = ((display_width/2), (display_height/2))
                    screen.blit(TextSurf, TextRect)
                    #add buttons to start screen
                    button("Go!",150, 450, 100, 50, green, bright_green, game_loop)
                    button("Quit",550, 450, 100, 50, red, bright_red, quitgame)
                    
                    pygame.display.update()
                    clock.tick(15)
                
            def game_loop():
             
                # Game Loop
                running = True
                while running:
                
                    # RGB = Red, Green, Blue
                    screen.fill((0, 0, 0))
                    # Background Image
                    screen.blit(background, (0, 0))
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            running = False
                
                        # if keystroke is pressed check whether its right or left
                        if event.type == pygame.KEYDOWN:
                            if event.key == pygame.K_LEFT:
                                playerX_change = -5
                            if event.key == pygame.K_RIGHT:
                                playerX_change = 5
                            if event.key == pygame.K_SPACE:
                                if cannon_state == "ready":
                                    cannonSound = mixer.Sound("cannon_x.wav")
                                    cannonSound.play()
                                    # Get the current x cordinate of the spaceship
                                    cannonX = playerX
                                    fire_cannon(cannonX, cannonY)
                
                        if event.type == pygame.KEYUP:
                            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                                playerX_change = 0
                
                    # 5 = 5 + -0.1 -> 5 = 5 - 0.1
                    # 5 = 5 + 0.1
                
                    playerX += playerX_change
                    if playerX <= 0:
                        playerX = 0
                    elif playerX >= 736:
                        playerX = 736
                
                    # ship Movement
                    for i in range(num_of_ships):
                
                        # Game Over
                        if shipY[i] > 440:
                            for j in range(num_of_ships):
                                shipY[j] = 2000
                            game_over_text()
                            break
                
                        shipX[i] += shipX_change[i]
                        if shipX[i] <= 0:
                            shipX_change[i] = 1               #######SHIP MOVEMENT
                            shipY[i] += shipY_change[i]
                        elif shipX[i] >= 736:
                            shipX_change[i] = -1              ######SHIP MOVEMENT
                            shipY[i] += shipY_change[i]
                
                        # Collision
                        collision = isCollision(shipX[i], shipY[i], cannonX, cannonY)
                        if collision:
                            explosionSound = mixer.Sound("explosion.wav")
                            explosionSound.play()
                            cannonY = 480
                            cannon_state = "ready"
                            score_value += 1
                            shipX[i] = random.randint(0, 736)
                            shipY[i] = random.randint(50, 150)
                
                        ship(shipX[i], shipY[i], i)
                
                    # cannon Movement
                    if cannonY <= 0:
                        cannonY = 480
                        cannon_state = "ready"
                
                    if cannon_state == "fire":
                        fire_cannon(cannonX, cannonY)
                        cannonY -= cannonY_change
                
                    player(playerX, playerY)
                    show_score(textX, testY)
                    pygame.display.update()
            
            game_intro()
  • 1
    Please go through the [intro tour](https://stackoverflow.com/tour), the [help center](https://stackoverflow.com/help) and [how to ask a good question](https://stackoverflow.com/help/how-to-ask) to see how this site works and to help you improve your current and future questions, which can help you get better answers. Stack Overflow is not intended to replace existing tutorials and documentation. – Prune May 08 '21 at 02:45
  • 1
    Most of all, you seem to need to practice more with basic Python operations before you attack a program. You cannot "call" a variable. Python does not declare variables. – Prune May 08 '21 at 02:46
  • Also see how to make a [mcve] – 12944qwerty May 08 '21 at 02:46
  • Please provide the expected see [MRE - Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). You've posted about 250 lines of code to ask a question about basic variable use and scoping. This is excessive. Please repeat your tutorial materials on functions; learn how to pass values between a function and the calling program. With that knowledge, do your best to fix your scoping problems here. If you get stuck, then post an appropriately focused question. – Prune May 08 '21 at 02:47

2 Answers2

0

If what you need is to be able to use a global variable in a function all you need is the keyword global.

x = 0
def inc() :
  global x
  x += 1
inc()
print(x)
Tom Lee
  • 360
  • 1
  • 3
  • 10
  • There is almost *never* a **need** for a global variable. It's a primary sign of poor design. – Prune May 08 '21 at 02:56
  • I have no idea what the guy is asking about. So ya. – Tom Lee May 08 '21 at 02:59
  • If you don't understand the question, then you shouldn't post an answer. Perhaps a comment ... once you've accumulated enough reputaiton. – Prune May 08 '21 at 02:59
  • See what you should do if you [cannot comment](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead/214174#214174) – 12944qwerty May 08 '21 at 03:02
0

You are referring a variable which is declared outside the function. Your function have no idea that they exists, therefor they through the error.

To use those variables inside your function you need to declare them as global.

This is what you need to do

def game_loop():

    global playerX
    global playerX_change
    global cannonX
    global cannonY
    global cannon_state

You can do this to other functions as well

Utpal Kumar
  • 300
  • 2
  • 13