我正在处理一个游戏并得到一个奇怪的错误,其中实例变量未正确保存(据我所知)。当我尝试从RunGame实例访问self.game时会发生这种情况。顺便说一下,这些类是在单独的模块中,并且我没有显示所有代码。游戏运行正常,但是当切换级别时它只会崩溃
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 \ python projects \ breakout \ PythonApplication1 \ PythonApplication1 \ GameHandler.py”,第30行,在switchLevel中 self.game.run = False #calling这将不会出现属性错误 AttributeError:'RunGame'对象没有属性'game' 按任意键继续 。 。
答案 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()