2016-05-02 77 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