title: class variable reference problem in pygame little game
body: <p>i am self learning pygame, so with help of tutorials i have created following little game :</p>
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  from pygame.locals import  *
  from pygame import mixer
  from os import path
  import pickle
  import pygame
  pygame.mixer.pre_init(44100,-16,2,512)
  mixer.init()
  pygame.init()
  screen_width =800
  screen_height =800
  screen =pygame.display.set_mode((screen_width,screen_height))
  pygame.display.set_caption(&quot;Platformer&quot;)
  sky_img =pygame.image.load(&quot;sky.png&quot;)
  sun_img =pygame.image.load(&quot;sun.png&quot;)
  restart_img =pygame.image.load(&quot;restart_btn.png&quot;)
  start_image =pygame.image.load(&quot;start_btn.png&quot;)
  exit_image =pygame.image.load(&quot;exit_btn.png&quot;)
  clock =pygame.time.Clock()
  pygame.mixer.music.load(&quot;music.wav&quot;)
  pygame.mixer.music.play(-1,0.0,5000)
  fps =60
  tile_size =40
  score= 0
  white=(255,255,255)
  blue =(0,0,255)
  font =pygame.font.SysFont('Bauhaus 93',70)
  font_score =pygame.font.SysFont('Bauhaus 93',30)
  #pickle_in =open(&quot;level7_data&quot;,'rb')
  #world_data =pickle.load(pickle_in)
  coin_fx = pygame.mixer.Sound('coin.wav')
  coin_fx.set_volume(0.5)
  jump_fx = pygame.mixer.Sound('jump.wav')
  jump_fx.set_volume(0.5)
  game_over_fx = pygame.mixer.Sound('game_over.wav')
  game_over_fx.set_volume(0.5)
  def draw_text(text,font,text_col,x,y):
      img =font.render(text,True,text_col)
      screen.blit(img,(x,y))
  def reset_level(level):
      player.reset(100,screen_height-100)
      platform_group.empty()
      blob_group.empty()
      lava_group.empty()
      exit_group.empty()
      if path.exists(f'level{level}_data'):
          pickle_in =open(f'level{level}_data','rb')
          world_data =pickle.load(pickle_in)
      world =World(world_data)
      return world
  blob_group = pygame.sprite.Group()
  lava_group =pygame.sprite.Group()
  exit_group =pygame.sprite.Group()
  coin_group = pygame.sprite.Group()
  
  game_over =0
  main_menu =True
  level =0
  max_levels =7
  class Exit(pygame.sprite.Sprite):
      def __init__(self,x,y):
          pygame.sprite.Sprite.__init__(self)
          ex_image =pygame.image.load('exit.png')
          self.image =pygame.transform.scale(ex_image,(tile_size,int(tile_size*1.5)))
          self.rect =self.image.get_rect()
          self.rect.x =x
          self.rect.y =y
  
  class World():
      def __init__(self,data):
          self.tile_list =[]
          wall_imag =pygame.image.load(&quot;dirt.png&quot;)
          grass_img =pygame.image.load(&quot;grass.png&quot;)
          row_count =0
          for row in data:
              col_count =0
              for tile in row:
                  if tile ==1:
                      img =pygame.transform.scale(wall_imag,(tile_size,tile_size))
                      img_rect =img.get_rect()
                      img_rect.x =col_count*tile_size
                      img_rect.y =row_count*tile_size
                      tile =(img,img_rect)
                      self.tile_list.append(tile)
                  if tile == 2:
                      img = pygame.transform.scale(grass_img, (tile_size, tile_size))
                      img_rect = img.get_rect()
                      img_rect.x = col_count * tile_size
                      img_rect.y = row_count * tile_size
                      tile = (img, img_rect)
                      self.tile_list.append(tile)
                  if tile ==3:
                      blob =Enemy(col_count*tile_size,row_count*tile_size+15)
                      blob_group.add(blob)
                  if tile == 4:
                      platform = Platform(col_count * tile_size, row_count * tile_size, 1, 0)
                      platform_group.add(platform)
                  if tile == 5:
                      platform = Platform(col_count * tile_size, row_count * tile_size, 0, 1)
                      platform_group.add(platform)
                  if tile ==6:
                      lava =Lava(col_count*tile_size,row_count*tile_size+(tile_size)//2)
                      lava_group.add(lava)
                  if tile==7:
                      coin =Coin(col_count*tile_size+(tile_size//2),row_count*tile_size+(tile_size//2))
                      coin_group.add(coin)
                  if tile==8:
                      exit =Exit(col_count*tile_size,row_count*tile_size-(tile_size)//2)
                      exit_group.add(exit)
                  col_count+=1
              row_count+=1
      def draw(self):
          for tile in self.tile_list:
              screen.blit(tile[0],tile[1])
  class Button():
      def __init__(self,x,y,image):
          self.image =image
          self.rect =self.image.get_rect(center = (x, y))
          #self.x =x
          #self.y =y
          self.clicked =False
  
      def draw(self):
          action =False
          pos =pygame.mouse.get_pos()
          if self.rect.collidepoint(pos):
              if pygame.mouse.get_pressed()[0]==1 and self.clicked==False:
                  action =True
                  self.clicked =True
          if pygame.mouse.get_pressed()[0] ==0:
              self.clicked =False
          screen.blit(self.image,self.rect)
          return action
  class Platform(pygame.sprite.Sprite):
      def __init__(self,x,y,move_x,move_y):
          pygame.sprite.Sprite.__init__(self)
          platform_image =pygame.image.load(&quot;platform.png&quot;)
          self.image =pygame.transform.scale(platform_image,(tile_size,tile_size//2))
          self.rect =self.image.get_rect()
          self.rect.x = x
          self.rect.y = y
          self.move_counter = 0
          self.move_direction = 1
          self.move_x = move_x
          self.move_y = move_y
      def update(self):
          self.rect.x+=self.move_direction*self.move_x
          self.rect.y+=self.move_direction*self.move_y
          self.move_counter+=1
          if abs(self.move_counter)&gt;50:
              self.move_direction*=-1
              self.move_counter*=-1
  
  class Player():
      def __init__(self,x,y):
          self.reset(x,y)
      def reset(self,x,y):
          self.images_right = []
          self.images_left = []
          self.index = 0
          self.counter = 0
          for num in range(1, 5):
              player_img = pygame.image.load(f'guy{num}.png')
              player_img = pygame.transform.scale(player_img, (40, 80))
              player_imag_Left = pygame.transform.flip(player_img, True, False)
              self.images_right.append(player_img)
              self.images_left.append(player_imag_Left)
  
          self.dead_image = pygame.image.load('ghost.png')
          self.image = self.images_right[self.index]
          self.rect = self.image.get_rect()
          self.rect.x = x
          self.rect.y = y
          self.vel_y = 0
          self.width = self.image.get_width()
          self.height = self.image.get_height()
          self.jumped = False
          self.direction = 0
          self.in_air =True
      def update(self,game_over):
  
          dx = 0
          dy =0
          walk_cooldown =5
          col_thresh = 20
          if game_over==0:
              key =pygame.key.get_pressed()
              if key[pygame.K_SPACE] and self.jumped ==False and self.in_air==False:
                  jump_fx.play()
                  self.vel_y =-15
                  self.jumped =True
              if key[pygame.K_SPACE] == False:
                  self.jumped = False
              if key[pygame.K_LEFT] ==True:
                  dx -=5
                  self.counter+=1
                  self.direction =-1
              if key[pygame.K_RIGHT] ==True:
                  dx +=5
                  self.counter += 1
                  self.direction=1
              if key[pygame.K_LEFT]==False and  key[pygame.K_RIGHT]==False:
                  self.counter =0
                  self.index =0
              if self.direction==1:
                      self.image =self.images_right[self.index]
              if self.direction==-1:
                  self.image = self.images_left[self.index]
              if self.counter &gt;walk_cooldown:
                  self.counter =0
                  self.index+=1
                  if self.index&gt;=len(self.images_right):
                      self.index =0
                  if self.direction==1:
                      self.image =self.images_right[self.index]
                  if self.direction==-1:
                      self.image = self.images_left[self.index]
              self.vel_y +=1
              if self.vel_y &gt;25:
                  self.vel_y =25
              dy +=self.vel_y
              self.in_air =True
              for tile in world.tile_list:
                  if tile[1].colliderect(self.rect.x+dx,self.rect.y,self.width,self.rect.height):
                      dx =0
                  if tile[1].colliderect(self.rect.x,self.rect.y+dy,self.width,self.height):
                      if self.vel_y &lt;0:
                          dy =tile[1].bottom -self.rect.top
                          self.vel_y =0
                      elif self.vel_y&gt;=0:
                          dy =tile[1].top -self.rect.bottom
                          self.vel_y=0
                          self.in_air =False
              if pygame.sprite.spritecollide(self,blob_group,False):
                  game_over_fx.play()
                  game_over =-1
  
  
              if pygame.sprite.spritecollide(self,lava_group,False):
                  game_over_fx.play()
                  game_over =-1
  
              if pygame.sprite.spritecollide(self,exit_group,False):
                  game_over=1
              for platform in platform_group:
                  # collision in the x direction
                  if platform.rect.colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
                      dx = 0
                  # collision in the y direction
                  if platform.rect.colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
                      # check if below platform
                      if abs((self.rect.top + dy) - platform.rect.bottom) &lt; col_thresh:
                          self.vel_y = 0
                          dy = platform.rect.bottom - self.rect.top
                      # check if above platform
                      elif abs((self.rect.bottom + dy) - platform.rect.top) &lt; col_thresh:
                          self.rect.bottom = platform.rect.top-1
                          self.in_air = False
                          dy = 0
                      # move sideways with the platform
                      if platform.move_x != 0:
                          self.rect.x += platform.move_direction
  
              self.rect.x +=dx
              self.rect.y +=dy
              if self.rect.bottom &gt;screen_height:
                  self.rect.bottom =screen_height
                  dy =0
          elif game_over==-1:
              self.image =self.dead_image
              draw_text(&quot;Game Over&quot;,font,blue,(screen_width//2)-200,screen_height//2)
              if self.rect.y &gt;200:
                  self.rect.y-=5
  
  
          screen.blit(self.image,self.rect)
          return game_over
  class Enemy(pygame.sprite.Sprite):
      def __init__(self,x,y):
          pygame.sprite.Sprite.__init__(self)
          self.image =pygame.image.load(&quot;blob.png&quot;)
          self.rect =self.image.get_rect()
          self.rect.x =x
          self.rect.y =y
          self.move_direction =1
          self.move_counter =0
      def update(self):
          self.rect.x +=self.move_direction
          self.move_counter+=1
          if abs(self.move_counter)&gt;50:
              self.move_direction *=-1
              self.move_counter *=-1
          pygame.draw.rect(screen,(255, 255, 255),self.rect)
  class Lava(pygame.sprite.Sprite):
      def __init__(self,x,y):
          pygame.sprite.Sprite.__init__(self)
          lava_image =pygame.image.load(&quot;lava.png&quot;)
          self.image =pygame.transform.scale(lava_image,(tile_size,tile_size//2))
          self.rect =self.image.get_rect()
          self.rect.x =x
          self.rect.y =y
  class Coin(pygame.sprite.Sprite):
      def __init__(self,x,y):
          pygame.sprite.Sprite.__init__(self)
          coin_image =pygame.image.load(&quot;coin.png&quot;)
          self.image =pygame.transform.scale(coin_image,(tile_size//2,tile_size//2))
          self.rect =self.image.get_rect()
          self.rect.center=(x,y)
  
  platform_group = pygame.sprite.Group()
  #world =World(world_data)
  player =Player(100,screen_height-120)
  restart_button = Button(screen_width//2, screen_height //2, restart_img)
  start_button = Button(screen_width//2, screen_height//2-100, start_image)
  exit_button = Button(screen_width//2, screen_height//2 + 200, exit_image)
  
  def draw_grid():
      for line in range(0,tile_size+1):
          pygame.draw.line(screen,(255,255,255),(0,line*tile_size),(screen_width,line*tile_size))
          pygame.draw.line(screen, (255, 255, 255), (line * tile_size,0), (line * tile_size,screen_height))
  #load in level data and create world
  if path.exists(f'level{level}_data'):
      pickle_in = open(f'level{level}_data', 'rb')
      world_data = pickle.load(pickle_in)
  world = World(world_data)
  run =True
  while  run :
      clock.tick(fps)
  
      screen.blit(sky_img,(0,0))
  
      screen.blit(sun_img, (100, 100))
      if main_menu==True:
          if exit_button.draw():
              run =False
          if start_button.draw()==True:
              main_menu=False
      else:
  
      #draw_grid()
  
          world.draw()
  
  
          if game_over == 0:
              blob_group.update()
              platform_group.update()
              if pygame.sprite.spritecollide(player,coin_group,True):
                  coin_fx.play()
                  score += 1
              draw_text('X'+str(score),font_score,white,tile_size-10,10)
  
          blob_group.draw(screen)
          platform_group.draw(screen)
          lava_group.draw(screen)
          exit_group.draw(screen)
          coin_group.draw(screen)
          game_over = player.update(game_over)
          if game_over==-1:
              if restart_button.draw():
                  world_data =[]
                  world =reset_level(level)
                  game_over =0
                  score=0
          if game_over==1:
              level+=1
              if level&lt;=max_levels:
                  world_data =[]
                  world =reset_level(level)
                  game_over=0
              else:
                  draw_text(&quot;you won&quot;,font,blue,(screen_width // 2) - 140, screen_height // 2)
                  if restart_button.draw():
                      level =1
                      world_data =[]
                      world =reset_level(level)
                      game_over=0
                      score=0
      for event in pygame.event.get():
          if event.type ==pygame.QUIT:
              run =False
      pygame.display.update()
  pygame.quit()
  </code></pre>
  <p>game works as fine,</p>
  <pre><code>but have several issues, one issue is  this line :
                      if platform.move_x != 0:
                          self.rect.x += platform.move_direction
  </code></pre>
  <p>it colors  as yellow color and says :
  <a href="https://i.stack.imgur.com/zdrJM.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zdrJM.png" alt="enter image description here" /></a></p>
  <p>in shortly it says that <code>Unresolved attribute reference 'move_x' for class 'Sprite'</code>  , the same is for  platform.move_direction, but  in Platform class we have both parameters and both are added here :</p>
  <pre><code>if tile == 4:
                      platform = Platform(col_count * tile_size, row_count * tile_size, 1, 0)
                      platform_group.add(platform)
                  if tile == 5:
                      platform = Platform(col_count * tile_size, row_count * tile_size, 0, 1)
                      platform_group.add(platform)
  </code></pre>
  <p>also there is second issue :in game player can't stand  on  moving platform, i mean this picture :
  <a href="https://i.stack.imgur.com/Cmqts.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Cmqts.png" alt="enter image description here" /></a></p>
  <p>if player is on platform, it falls down, how can i fix this issue? thanks in advance</p>