2015-07-04 79 views
2

Atm我正在使用tkinter進行遊戲。我正在研究通過遊戲地圖移動敵人的算法。Python線程執行兩次函數

我將只發布相關線路,因爲代碼是埋頭苦幹閱讀。

我使用的是從線程進口類定時器。 2相關的功能有:

def add_enemies(self): 
    enemy = self.enemies.pop(0) 
    if enemy in '.': 
    Timer(1, self.add_enemies).start() 
    else: 
    self.move_enemy(enemy,set()) 
    if not self.game_ended and self.enemies: 
     Timer(1, self.add_enemies).start() 

def move_enemy(self, enemy, visited): 
    if type(enemy) == str: 
    if enemy in 'm': 
     enemy = Mongol(self.canvas, *self.start) 
    visited.add((enemy.x,enemy.y)) 
    for move in (-1,0),(0,1),(1,0),(0,-1): 
     pos = (enemy.x + move[0], enemy.y+move[1]) 
     if pos in self.way and pos not in visited: 
      print(pos) 
      enemy.move(*move) 
      enemy.take_shot(6) 
      visited.add(pos) 
      Timer(0.5, lambda: self.move_enemy(enemy, visited)).start() 

這個功能應該移動的敵人,等待0.5秒,再創建一個線程在它遞歸調用自身,並再次移動的敵人。

它可能不是最好的解決方案的創建線程內另一個線程,但所有其他解決方案,使我的GUI在執行功能凍結。

問題是,即定時器執行功能move_enemy兩次。代碼中沒有其他內容會導致此問題。的敵人位置

簡單打印測試表明這一點:

它只是簡單地移動所述敵人兩次,兩次增加其位置上的圖像,如圖所示。

+0

你需要發佈更多的路線,爲我們製作一個MCVE。 http://stackoverflow.com/help/mcve – CrazyCasta

+0

將你的代碼添加到問題 –

+0

你真的想用你的線條來做什麼,比如'if'in'y''?另外,一旦您在'move_enemy'中創建了一個新的'Timer',爲什麼還要繼續研究其他可能的舉措? –

回答

0

問題是,那Tkinter的不是線程安全的,因此它不採取行動確定性。 我使用Queue解決了這個問題。我的主線程中,tkinter運行,定期檢查是否有畫東西。

0

這是胡亂猜測,但有一個新的enemy對象與修改過的位置在 Timer(0.5, lambda: self.move_enemy(enemy, visited)).start()代替enemy對象可能得到其間的座標((3,1),(5,1)等)。 (如果你用相同的輸入做同樣的事情兩次,你會得到兩個相同的值)

從輸出I推斷:visited.add(pos)沒有位置添加到visited因此if pos in self.way and pos not in visited:條款沒有過濾掉已經測試值(因此(2,1)(2,1)打印輸出)。試試,如果.append()效果更好。

我盡力:d GL HF

0

從輸出來看,它看起來像什麼是真正發生的是你期待的事情順序

print 
move 
print 
move 
print 
move 
print 
move 
.... 

執行,但你沒有包括足夠的同步和它們發生,而不是在這個順序:

print 
print 
move 
move 
print 
print 
move 
move 
.... 

它沒有做任何事情額外:它只是在按照你所希望的順序做事。