2015-12-29 2 views
-2

Im работает над игрой и получает странную ошибку, когда переменная экземпляра не сохраняется должным образом (насколько я могу судить). Это происходит, когда я пытаюсь получить доступ к self.game из экземпляра RunGame. Кстати, классы находятся в отдельных модулях, а im не отображают весь код. Игра работает нормально, но при переключении уровня он просто падаетПолучение ошибки атрибута для переменной, отличной от атрибута

class RunGame(object): 

    def __init__(self): 
     self.makeTk() 
     self.currentLevel = 0 
     self.bricksLayout = [   #for debugging: a layout of bricks. 3d array with each level 
      [ 
        [0,1,0,1,1,1,1,1], 
        [0,0,0,0,4,1,1,1], 
        [4,4,4,4,4,4,4,4] 
       ], 

       [ 
        [4,0,0,1,0,1,0,1], 
        [0,0,0,0,0,1,0,1], 
        [4,4,4,4,4,4,4,4] 
       ] 

      ] 

     self.game = GameInstance(self.bricksLayout,self) 
     self.game.run = False  #this does nothing for some reason, no error though 

    def switchLevel(self): 
     print("switching level") 
     self.game.run = False  #calling this will give no attribute error 

     #self.game.clearCanvas() 
     #self.game.canvas.destroy() 
     self.currentLevel+=1 
     #self.game = Game(self.bricksLayout,self) 

    def makeTk(self): 
     self.root = Tk() 
     self.root.title("PrakeOut") 
     self.screen_width = self.root.winfo_screenwidth(); #monitor size 
     self.screen_height = self.root.winfo_screenheight(); 
     #root.wm_attributes("-fullscreen",True)  #this gives fullscreen, but removes the menu 
     self.root.resizable(0,0) #cant be resized 
     self.root.configure(background="Black")  #bg color of root windw 
     #root.geometry("%ix%i+0+0" % (SCREEN_WIDTH, SCREEN_HEIGHT)) #maximizes screen. First two are width and height, other two are x1 and y1 
     #root.wm_attributes("-topmost",1); #places window in foreground 

run = RunGame() 

class GameInstance(object): 


    def __init__(self, bricksLayout,gameHandler): 
     self.bricksLayout = bricksLayout 
     self.gameHandler = gameHandler 
     self.run = True  #game loop 

     self.makeCanvas() 

     self.brickList = [] #the list of all da created bricks 
     self.makeBricks() 
     self.makeBallAndPaddle() 

     self.gameLoop() 
     self.root.mainloop(); #needs to run main loop otherwise windows doesnt show 

Это дает эту ошибку:

Файл «C: \ Users \ Bollen \ Desktop \ питона проекты \ прорыве \ PythonApplication1 \ PythonApplication1 \ GameHandler. py ", строка 30, в switchLevel self.game.run = False #calling это не даст никакой ошибки атрибута AttributeError: объект 'RunGame' не имеет атрибута 'game' Нажмите любую клавишу, чтобы продолжить. , ,

+0

код, который вы опубликовано не может дать ошибку, о которой вы говорите, потому что она имеет другие ошибки. –

+0

Это очень полезно. –

ответ

0

Мы не можем использовать ваш код, чтобы воспроизвести проблему, но в коде есть одна очень очевидная логическая ошибка. Проблема в том, что ни один из ваших классов не может быть полностью создан до их использования.

Взгляните на GameInstance: потому что вы звоните mainloop в инициализаторе, что класс никогда не будет полностью проиллюстрированный до после того, как окно корень был создан , а затем уничтожили. Поэтому любые другие классы, которые пытаются работать с этим экземпляром, будут работать с не полностью сформированным экземпляром.

Аналогичным образом, с GameRunner вы создаете экземпляр GameInstance. Поскольку GameInstance вызывает mainloop, создание объекта GameRunner не может быть закончено до того, как будет создано GameInstance, а GameInstance не будет закончено, пока не будет уничтожено окно.

Первый шаг заключается в том, чтобы удалить звонок mainloop из GameInstance.__init__. Вместо этого переместите это в метод, который GameRunner может вызвать, когда он полностью создан.

Вы также должны отделить создание двух объектов на два этапа. Ваша основная логика будет выглядеть примерно так:/Я не уверен, что сначала нужно создать бегун или игру, но в любом случае это приемлемо в зависимости от того, как вы определяете классы.

game = GameInstance(...) 
runner = GameRunner(..., game) 
runner.run() 

В приведенном выше, runner.run() будет выглядеть примерно так:

class GameRunner(...): 
    def run(self): 
     self.game.run() 

... и game.run будет выглядеть следующим образом:

class GameInstance(...): 
    def run(self): 
     self.gameLoop() 
     self.root.mainloop() 
Смежные вопросы