title: Python pygame function not defined
body: <p>I've been asked to find a problem with my cousin's Pygame code. I'm not big on Python, using other languages more and I haven't been able to find the issue by googling or debugging. Basically he's getting a <em>"<code>playGame</code> is not defined"</em> error, <code>playGame</code> being a function. Other questions about this are usually because:</p>
  
  <ol>
  <li>The function is called before it is declared</li>
  <li>The function is declared inside a different scope from which it is called</li>
  </ol>
  
  <p>Neither of these seems to be the issue so I'm hoping someone more versed in Python can spot it. I've copied his code below with a lot of what (I hope) is irrelevant to the question removed to simplify.</p>
  
  <p>The function <code>playGame</code> is not working and is called by a button click under
  <code>def button(msg, x, y, action = None):</code>
  . Interestingly the exit function is working fine which is called and declared exactly the same as <code>playGame</code> as far as I can tell.</p>
  
  <pre><code># --------------- SETUP ---------------
  # Importing necessary modules
  import pygame
  import math
  import random
  # --------------- DISPLAY ---------------
  # Setting up the display
  pygame.init()
  screen = pygame.display.set_mode((width, height))
  pygame.display.set_caption(title)
  # --------------- GLOBALS ---------------
  #removed globals from stackoverflow version
  
  
  # --------------- FUNCTIONS ---------------
  
  
  # Blitting the text
  def blitText(angle, power):
      #code
  
  
  # Drawing the tank model
  def drawTank():
      #code
  
  
  # Creating the buttons
  def button(msg, x, y, action = None):
      mousePos = pygame.mouse.get_pos()                                                                           # Gets the mouse position
      mouseClick = pygame.mouse.get_pressed()
  
      (buttonWidth, buttonHeight) = (175, 45)                                                                     # Sets the button width and height
      if x + (buttonWidth / 2) &gt; mousePos[0] &gt; x - (buttonWidth / 2) and y + buttonHeight &gt; mousePos[1] &gt; y:      # Checks if the mouse is over the button
          pygame.draw.rect(screen, darkGrey, [x - (buttonWidth / 2), y, buttonWidth, buttonHeight])                   # Draws a dark grey button
          if mouseClick[0] == 1 and action != None:                                                                   # Checks if the button is clicked
              if action == "play":
                  playGame()
              elif action == "exit":
                  exit()
      else:
          pygame.draw.rect(screen, grey, [x - (buttonWidth / 2), y, buttonWidth, buttonHeight])                       # Draws a light grey button if not
  
      screen.blit(msg, [x - (buttonWidth / 2), y])                                                                # Writes the text over the button
  
  
  # Defining the shell
  class shell(pygame.sprite.Sprite):              # Creates the shell() class
      def __init__(self):                             # Defines an initiation fuction for this class
          super().__init__()                              # Call the parent class constructor
          self.image = pygame.Surface([2, 2])             # Defines the bullet as a 2x4 surface
          self.image.fill(black)                          # Paints the bullet black
          self.rect = self.image.get_rect()               # Gets the area size of the bullet
  
      def update(self):                                                                                                                               # Defines a function as update for this class
          (bulletChangeX, bulletChangeY) = (((maxAngle - angle) / maxAngle) * (bulletSpeed * power), (angle / maxAngle) * (bulletSpeed * power))          # Ccalculates the changes in x and y
          bulletChangeY -= vert                                                                                                                           # Changes the trajectory of the bullet
          self.rect.y -= bulletChangeY                                                                                                                    # Moves the bullet in the y axis
          self.rect.x += bulletChangeX                                                                                                                    # Moves the bullet in the x axis
  
  
  # --------------- TITLE SCREEN ---------------
  # Creating the main menu
  menu = True
  while menu:                                                     # Starts the loop
      for event in pygame.event.get():
          if event.type == pygame.QUIT:                                   # Checks if pygame has been closed
              exit()                                                          # Exits python
      screen.fill(white)                                              # Fills the screen white
      screen.blit(titleText, [0, 0])                                  # Writes the title text
  
      button(startButton, width / 2, (height / 3) * 2, "play")      # Calls the button function for the start button
      button(exitButton, width / 2, ((height / 3) * 2) + 70, "exit")    # Calls the button function for the exit button
  
      # Updating the display
      pygame.display.update()                                         # Updates the display
      clock.tick(fps)
  # --------------- MAIN LOOP ---------------
  
  
  # Running the program
  def playGame():
      #code. This function has no return value.
  
  
  # --------------- EXIT ---------------
  
  
  # Exits PyGame and Python
  def exit():
      pygame.quit()
      quit()
  </code></pre>
  
  <p>Hopefully the mistake is obvious here to someone and I haven't removed any key code that is causing the problems (I removed start variable declarations and the contents of function code) I can provide the full code if people need it.</p>