2016-05-02 74 views
1

我已经创建了一个游戏。它的工作完美,所以我想我会添加一个屏幕来改变'子弹'的颜色。我做了窗口我分配变量我globaled我需要的变量,但是我不断收到一个错误说变量没有被定义,但该变量下定义和来自同一个'商店'功能下的其他变量是定义。如果我摆脱了正常,并且只有FireGun和LaserGun FireGun没有定义。很难解释。所以看看我已经非常糟糕的代码,看看你能否挑出任何错误。全局变量不通过,说它不被识别?

from tkinter import * 

def MainMenu(): 
    self = Tk() 

    self.btnShops = Button(text ="Shop") 
    self.btnShops.pack() 

    def startShops(event): 
     self.destroy() 
     Shop() 


    self.btnShops.bind('<Button>',startShops) 



    self.geometry("830x700") 
    self.title("Space Assault") 
    self.configure(bg="black") 



def Shop(): 
    self = Tk() 


    normal = 1 
    fire = 0 
    laser = 0 

    def FireGun(event): 
     global fire 
     global normal 
     global laser 
     fire = 1 
     normal = 0 
     laser = 0 

    def LaserGun(event): 
     global laser 
     global fire 
     global normal 
     laser = 1 
     fire = 0 
     normal = 0 


    self.btnfireGun = Button(text="Fire Gun") 
    self.btnfireGun.pack() 
    self.btnlaser = Button(text = "Laser Gun") 
    self.btnlaser.pack() 
    self.btnMainMenu = Button(text="Main Menu") 
    self.btnMainMenu.pack() 


#Bind 
    self.btnfireGun.bind('<Button>',FireGun) 
    self.btnlaser.bind('<Button>', LaserGun) 
    self.btnMainMenu.bind('<Button>',StartMainMenu) 

#Frame settings 
    self.geometry("830x700") 
    self.title("Space Assault Shop") 
    self.configure(bg="black") 

def singleplayergame(): 

    def Shoot(event): 
     global normal 
     global fire 
     global laser 

     self.shot = Canvas(bg="black",highlightthickness=0,width=10,height=10) 
     self.shot.place(x=shotXpos,y=shotYpos) 

     if normal == 1: 
      self.shot.create_oval(0,0,10,10,fill=random.choice(COLORS)) 
     elif fire == 1: 
      self.shot.create_oval(0,0,10,10,fill='red') 
     elif laser == 1: 
      self.shot.create_oval(0,0,10,10,fill='blue') 

MainMenu() 

如果我点击FireGun按钮子弹工作正常,他们出来像红色一样正常。但是,如果我想它'正常'它甚至不会发射任何东西。希望这是有道理的。我认为它与全球减速有关,但我真的坚持这一点。

回答

2

很多东西在继续。

你不应该像这样嵌套函数。如果你想封装数据/结构,那么只需使用一个类。你似乎想要通过命名Tk()自我并在自己的地方打电话给自己。这其实只是为Tk设置了一些属性。

您正在创建Tk()的多个实例。如果您想要新窗口,请使用Toplevel()小部件。否则,只需使用pack_forget/grid_forget来实质上隐藏您想要的框架/窗口小部件,并使用包/网格“取消隐藏”其他窗口以替换它们。

不需要运行多个Tk()实例。

你永远不会打电话mainloop

你打电话给global你的变量是不必要的,你可以重构。如果你使用全局变量9/10,你有一个XY problem。他们真的不是全球性的开始。它们对于你嵌套的函数是局部的。 如果您真的需要需要此结构,您可以使用nonlocal。再说一次,如果你想要一个像这样的结构,只需使用一个类并将它们保留为属性即可。

在所有按钮上不需要使用bind只需在点击时调用某个功能。这是command参数的用途。

1

在一个函数内定义一个全局变量只是告诉该函数使用指定的同名变量global。它本身不分配变量。如果您使用的是Python3,则可以使用nonlocal而不是global内部的shop函数中的嵌入函数声明嵌入函数使用shop的本地函数。

我看到您想要使用singleplayergame函数中的变量,因此请考虑在所有函数之外定义这些变量,然后通过global声明导入它们。

在这种情况下,将normal,firelaser变量移动到shop函数之外应该有所裨益。

希望这可以帮助,这里有一些链接来帮助Python的范围!

乔治

Python scoping: understanding LEGB

Setting a global variable in a function