2012-05-26 80 views
0

所以我有一個函數(下面),我想每2秒更改一個變量。目前該功能每2秒更換一次變量(goblinx)。問題是time.wait導致所有功能暫停2秒。我怎麼才能讓movegoblin()函數暫停。如何暫停一個pygame函數而不暫停其他人?

def movegoblin(): 
    global goblinx 
    global gobliny 
    x = 1 
    if x == 1: 
     goblinx += 32 
     pygame.time.wait(200) 
+1

使用多線程 –

+2

一個不需要多線程的這個事件循環與定時器支持也是成熟的技術 –

+0

儘管Pygame沒有內置的事件循環提供支持。實現它很容易 - 但比具有支持打字的字符基類更復雜。多線程對於這個問題的確是錯誤的。 – jsbueno

回答

-1
import _thread  
_thread.start_new_thread(movegoblin,()) 

或者如果你喜歡

import threading 
threading.Thread(target=movegoblin).start() 

與鎖:

mutex = _thread.allocate_lock() 
def movegoblin(): 
    global goblinx 
    global gobliny 
    x = 1 
    if x == 1: 
     mutex.acquire() 
     goblinx += 32 
     pygame.time.wait(200) 
     mutex.release() 
+0

加入線程後,會導致變量不受控制地增加,而其他函數很少會改變。幾秒鐘後,我得到一個錯誤'錯誤:無法啓動新線程'我從來沒有使用線程之前,所以我不知道該怎麼做。 @sajattack – enrique2334

+0

如果你多次調用它,你必須確保線程不與鎖相互重疊。在'goblinx + = 32'前後添加'mutex = _thread.allocate_lock','mutex.acquire()'和'mutex.release()' – sajattack

+0

另外,如果你不使用python 3,_thread就是線。 – sajattack

4

去這裏的路,是提高你的小妖精(和其他字符)處理的?你的程序從函數到適當的類,所以它們可以有內部狀態。

每一個這樣的類他們可以有它們在每場比賽幀更新,哪些變量觸發一個動作,當計數到達值。

這個解決方案不是增加併發線程只是定時會計cleanr,正確地完成,可導致應用程序設計至極將大力發展,擴大和保持幸福。

您可以採用的樣式的簡短示例,保留代碼中的功能。 (請注意,您可以使用pygame.sprite.Sprite類有「更新」方法authomaticaly呼籲每個對象組 - 我會做從頭波紋管)

frame_delay = 20

class Goblin(object): 
    def __init__(self): 
     self.x = 1 #or whatever 
     self.y = 1 #or whatever 
     self.movement_count = 0 
     self.move_at_each = 10 

    def move(self): 
     self.movement_count += 1 
     if self.movement_count < self.move_at_each: 
      return 
     self.movement_count = 0 
     self.x += 32 

在你的主循環中,你實例化一個哥布林:

goblin = Goblin(),在進入while循環之前,並且在每一幀調用goblin.move()。 這樣你就可以擁有一個合適的地精類,這將允許你在遊戲中擁有多個「地精」 - 而你的例子中的代碼將要求你對每個字符進行硬編碼。你只需在遊戲的每一幀都調用「goblin.move」方法。上面的例子被調整以移動每個10幀,但是你可以改變它(並且可以改變你實例化的每個單獨的精靈)。如上所述,pygame提供了「Sprite」和「sprite groups」類作爲這種機制的框架,但在一些較小的遊戲中滾動你自己將有助於你更好地理解需求和pygame精靈已經提供了,這樣你就可以在以後的項目(或項目的後期階段)使用它們

1

簡單的答案:

呼叫你的妖精每一幀.update()函數。如果時間超過> = 200毫秒,然後移動他。否則什麼都不做。

class Unit(): 
    def __init__(self): 
     self.update_delay = 200 
     self.last_update = pygame.time.get_ticks() 

    def update(self): 
     # call once per game update. 
     now = pygame.time.get_ticks() 
     if now - self.last_update >= self.update_delay: 
      self.last_update = now 

      # update AI , pathfind , etc. 
      self.x += 30 
0

我想大多數人會首先想到的答案就是這樣的:「你在想錯誤的方法!」 - 如果你遵循傳統的gamedev方法,這實際上是真的; jsbueno和猴子告訴你,你通常會去那裏。

我只是想指出一個Python項目,試圖給你抓住了問題的方式加以解決。要求是:真實世界是併發的,所以你應該以並行的方式對其進行建模(事實上,你的直觀方法是併發的,支持這一點)。

問題是,在問題上使用真正的多線程方法肯定會給你更多的問題,因爲你必須考慮競爭條件等等(因此sajattack的答案中的互斥量)。如果你的遊戲中有數以百計的精靈/對象(如果你想開始大思考的話,這個數字並不是很高的數字,認爲數以萬計的數字)對於處理它的窮人計算機很可能是矯枉過正的。

這就是爲什麼一些人開始了一個名爲stackless python的項目。他們想給一個工具,讓你編程併發沒有多線程!有了這個,你可以按照你的建議進行編程,有一個功能正在等待,而另一些則繼續運行。他們稱之爲微螺紋的概念還有一篇相當不錯的文章給你introduction to concurrent thinking in programming。您可能想看看該項目,但這可能會給您帶來幾個問題:

  1. 您將需要不同版本的python解釋器。 Stackless不是標準的c-python或pypy,很可能不會很快。
  2. 事實上,你使用不同的解釋器將使分發任何用無堆棧python編寫的遊戲變得更加困難。
  3. 您可能會學到一種不尋常的遊戲編程方式 - 這在未來的某個時間(或者可能不會)很重要。在與現實生活中的程序員交談時或在閱讀現有遊戲來源時可能會給您帶來麻煩。首先做一些經典的遊戲編程或者除了堆棧之外可能是個好主意。