2013-10-20 52 views
0

我正在用python tkinter模塊使用畫布小部件編寫一個小遊戲。 有人,只是一個球,每10秒產生一次炸彈。 在炸彈產生3秒後,它開始「爆炸」過程,我在self.bomb對象上調用4個更多的方法來「爆炸」它的動畫。在調用.after()方法之後取消事件?

遊戲的目的是試圖「解除」炸彈。我想出了一些奇特的碰撞檢測工作。

self.canvas.delete(self.bomb) 

然而,炸彈越來越大,變色(爆炸)仍然發生的下面的動畫,即使我已經「繳械」:一旦檢測到碰撞時,炸彈掉在畫布上的使用清除炸彈。這是因爲我原來的炸彈來電:

self.parent.after(3000, self.explode_first) 

...我已經鏈接3個「爆炸」功能,所有綁定並與。經過()方法調用。

我試圖通過在.after()中調用的每個方法中插入條件來繞過這個問題,就像布爾值;

if self.bomb # if there's a bomb on the canvas, 
    self.parent.after(125, self.explode_second) # and explode third and so on 

這是行不通的。我希望能夠「取消」使用after方法創建的tkinter隊列的事件,但這裏是踢球者。我不(無法)殺死所有的事件,只是在畫布上的事件。如果可能的話,我還有其他的事情要保持完整。

有沒有辦法做到這一點?如果沒有,歡迎提供有關如何在不事後取消的反饋和/或建議,並且提前致謝!

繼承人的相關代碼,以供參考:

​​

和:

# continuously make and explode bombs 
def create_bomb(self): 
    self.bomb = self.canvas.create_oval(self.b1, 
             self.b2, 
             self.b3, 
             self.b4, 
             fill = "red") 
    if self.bomb: 
     self.parent.after(3000, self.explode_first) 


def explode_first(self): 
    if self.bomb: 
     self.b1 -= 5 
     self.b2 -= 5 
     self.b3 += 5 
     self.b4 += 5 
     self.canvas.delete(self.bomb) 
     self.bomb = self.canvas.create_oval(self.b1, 
             self.b2, 
             self.b3, 
             self.b4, 
             fill = "orange") 
     self.parent.after(125, self.explode_second) 


def explode_second(self): 
    if self.bomb: 
     self.b1 -= 5 
     self.b2 -= 5 
     self.b3 += 5 
     self.b4 += 5 
     self.canvas.delete(self.bomb) 
     self.bomb = self.canvas.create_oval(self.b1, 
             self.b2, 
             self.b3, 
             self.b4, 
             fill = "yellow") 
     self.parent.after(125, self.explode_third) 


def explode_third(self): 
    self.b1 -= 5 
    self.b2 -= 5 
    self.b3 += 5 
    self.b4 += 5 
    self.canvas.delete(self.bomb) 
    self.bomb = self.canvas.create_oval(self.b1, 
             self.b2, 
             self.b3, 
             self.b4, 
             fill = "white") 
    self.parent.after(125, self.explode_fourth) 


def explode_fourth(self): 
    self.canvas.delete(self.bomb) 

def bomb_disarmed(self): 

    print "disarmed the bomb!" 
    self.canvas.delete(self.bomb) 
+0

更新:所以,我用canvas.find_above(self.ball):作爲條件,這似乎工作。然而,通過tkinter帆布的文檔查看,這看起來很渺茫,如果我不解除炸彈的武裝,它現在永遠保持在那裏,就像之前它們會爆炸一樣。 – ford

回答

0

您可以將屬性添加到你的工作是這樣的類:

self.isDisarmed = False 

然後將此行添加到bomb_disarmed

self.isDisarmed = True 

然後在explode_first,添加一個測試,看看炸彈撤防:

def explode_first(self): 
    if self.bomb: 
     if self.isDisarmed: 
      self.parent.after(125, self.explode_fourth) # If bomb is disarmed, skip to the last step, where the bomb is deleted. 
     else:            # Otherwise, carry on with bomb explosion 
      self.b1 -= 5 
      self.b2 -= 5 
      self.b3 += 5 
      self.b4 += 5 
      self.canvas.delete(self.bomb) 
      self.bomb = self.canvas.create_oval(self.b1, 
              self.b2, 
              self.b3, 
              self.b4, 
              fill = "orange") 
      self.parent.after(125, self.explode_second) 

作爲一般原則,我會建議做Bomb一類,它有它自己的內部屬性和方法。這將使跟蹤炸彈發生的情況以及結果應該如何變得更加容易,並且可以使炸彈等事情成爲可能。

編輯:

回覆:從另一個類的方法的App的畫布上繪製,這裏有一個方法:

class App: 
    def __init__(self, ...): 
     self.canvas = Tkinter.Canvas(...) 
     self.thingy = SomethingElse() 

class SomethingElse: 
    def __init__(self, parentApp): 
     self.parentApp = parentApp 
    def drawSomething(self): 
     self.parentApp.canvas.create_oval(...) 

a = App(...) 
s = SomethingElse(a) 
s.drawSomething() 
+0

我完全同意第二點,(我會努力實現和測試第一點),但我真的很努力能夠將其他對象添加到我在主類中初始化的畫布中。有什麼指針?我似乎無法以任何方式訪問應用程序類的畫布,而只能使用我構建到同一個類中的方法。 – ford

+0

嗯,不知道你的意思。只要將畫布對象傳遞給另一個方法,該方法應該能夠在畫布上繪製,而不管該方法屬於哪個類。 – Brionius

+0

但無論哪種方式,使App類的方法處理所有圖形,並且只需通過調用App類中的方法來繪製'Bomb'類「request」就會更清晰。 – Brionius

1

after方法返回一個代表調度的事件的ID。如果保存ID,您可以撥打after_cancel取消事件:

self.after_id = self.parent.after(3000, self.explode_first) 
... 
self.parent.after_cancel(self.after_id) 
相關問題