2014-10-28 94 views
0

我有一個遊戲,我已經寫了我的第一個項目,我想有一個系統,我可以玩和暫停遊戲。當你點擊取消暫停按鈕時,我希望它每1秒鐘調用一次函數來提前計算日期。 Time.sleep會停止整個程序,所以對我沒有用處,而且我無法在啓動線程後重新啓動線程。這是推進日的功能。Python每秒鐘都會調用一個函數?

def time(): 
    global timer 
    timer = threading.Timer(1.0, time) 
    timer.start() 
    thirtyonemonths = [1, 3, 5, 7, 8, 10, 12] 
    thirtymonths = [4, 6, 9, 11] 
    globalvars.day = globalvars.day + 1 
    for self in thirtyonemonths: 
     if self == globalvars.month: 
      print "hi" 
      if globalvars.day == 32: 
       globalvars.day = 1 
       globalvars.month = globalvars.month + 1 
    for self in thirtymonths: 
     if self == globalvars.month: 
      print "hi" 
      if globalvars.day == 31: 
       globalvars.day = 1 
       globalvars.month = globalvars.month + 1 
    if globalvars.month == 2: 
     print "hi" 
     if globalvars.day == 29: 
      globalvars.day = 1 
      globalvars.month = globalvars.month + 1 
    if globalvars.month == 13: 
     globalvars.month = 1 
     globalvars.year = globalvars.year + 1 
    threading.Thread.time(self) 
timer = threading.Timer(1.0, time) 

後來我當按鈕被點擊檢查它是否暫停或直到我按下按鈕第三次

if b.collidepoint(pos): 
    if globalvars.ispaused == 1: 
     globalvars.ispaused = 0 
     timer.start() 
     break 
    if globalvars.ispaused == 0: 
     globalvars.ispaused = 1 
     timer.cancel() 
     break 

一切完美彌補了代碼。有誰知道一種方式,我可以重新啓動線程或可能使用不同的方法來做我想要的?

+0

@Apero:他正在使用線程。這就是'threading.Timer'的意思。 – abarnert 2014-10-28 19:09:00

+0

http://stackoverflow.com/questions/8600161/executing-periodic-actions-in-python – 2014-10-28 19:11:49

+0

也看看這個:https://docs.python.org/2/library/sched.html – 2014-10-28 19:12:46

回答

0

沒有看到你的代碼的其餘部分,這是很難確定是哪裏的問題,但我的猜測是,有時,當你點擊按鈕,ispaused1,但timer是過期的計時器,而不是暫停一。在過期的定時器上調用start不起作用。

雖然這可以修復,但有更簡單的方法來做到這一點。

首先,它看起來像你在這裏使用某種GUI或遊戲框架。我不知道你在使用哪一個,但幾乎每個人都有一個定時器的功能(在主事件循環中,而不是在單獨的線程中,但這不是關鍵的事情),更多比threading.Thread強大 - 特別是,它可以每秒自動重複,直到取消。這顯然會讓你的生活更輕鬆。

如果不是,那麼編寫自己的重複Timerfind one on PyPI是很容易的。請注意,threading文檔以鏈接the source code開頭。這是因爲,就像stdlib中的許多模塊一樣,threading被寫成簡單易懂,充當示例代碼,本身就是有用的。特別是,Timer是簡單的,它應該是非常明顯的如何擴展它:只需要圍繞run方法進行循環。

+0

非常感謝您的回覆。當另一個人提供更簡單的解決方案時,我正在擴展Timer。 我結束了剛剛停止我的time()函數的內容,除非未暫停的變量等於1.這樣我就不需要啓動和停止線程。 – Taegis 2014-10-28 20:42:49

+1

儘管爲了將來的參考,當你說「擴展計時器」時,你的意思是把線程庫中的原始類的源代碼編輯並編輯它?我會複製課程並將其粘貼到我的源代碼中嗎?我從來沒有真正編輯過Python的庫。我假設我會重命名它並導入線程庫以及?除非你的意思完全不同。我是一個菜鳥:p – Taegis 2014-10-28 20:50:40

+1

或者你可以[擴展班級](http://stackoverflow.com/a/2706023/786020)。所以像'class MyTimer(threading.Timer):def run(self):while(True):threading.Timer.run(self)''。但不太可能。 – Poik 2014-10-28 21:03:32

0

在你的函數開始你新的全球每一個時間和一個計時器設置:這是沒有必要和必須

global timer 
timer = threading.Timer(1.0, time) 
timer.start() 

然後在函數結束時,您有threading.Thread.time(self)除去。然後在函數聲明後你有timer = threading.Timer(1.0, time)這可能是一個錯誤,因爲當它第一次被調用時,全局定時器可能還沒有被創建。將最後一行代碼替換爲time()以在第一次立即調用該函數。更改這兩行可能會將代碼修復得足夠好。

而且,你有你的這樣的循環:

for self in thirtyonemonths: 

以及與此問題可能是使用關鍵字self的。如果這個函數是在一個類中定義的,那麼這個self的使用可能被解釋爲對這個對象的引用。通常最好不要使用關鍵字self作爲迭代器。將自己的所有用法替換爲其他內容,比如m來改進您的代碼。

+0

啊,好的,謝謝。我在最後擺脫了這段代碼,並修復了「自我」的使用。 我結束了剛剛停止我的time()函數的內容,除非未暫停的變量等於1.這樣我就不需要啓動和停止線程。 – Taegis 2014-10-28 20:58:09