2013-02-25 60 views
0

我正在製作一個基於文本的RPG遊戲,我真的很想效仿時間。
我可以在每次玩家輸入一些東西之間進行一些時間傳遞,但是如果可能的話,它會比這更好。我想知道多線程是否是一個很好的方法來做到這一點。在文本冒險中實現實時?

我在想也許只是在後臺有一個第二個,非常簡單的線程,只有一個循環,每循環1000毫秒。對於通過其循環的每一次傳球,世界時間會增加1秒,並且玩家會恢復一點生命值和法力值。

這是多線程可以做的事,還是有一些我不知道的東西會使這不起作用? (如果它不會幫助我完成這個項目,我寧願不花費一些時間來學習這些東西。)

+0

http://www.cplusplus.com/reference/ctime/有什麼問題? – thiagoh 2013-02-25 04:35:20

+0

它會完成這項工作。但是如果你採取這種方法,它會讓你對熟悉互斥體的人產生一些傷心。 – 2013-02-25 04:36:05

+0

爲什麼有這樣的線程比替代方案更好? – 2013-02-25 04:40:08

回答

3

是的,多線程當然可以做到這一點,但是很疲倦,線程通常比替代方案(這將是主線程將各種更新事件作爲其主循環的一部分進行輪詢,無論如何它應該每100ms運行至少一次)。

在你的情況下,如果時鐘線程遵循相當嚴格的規則,你可能會「確定」。

  1. 時鐘線程是唯一允許設置/修改時間變量的線程。
  2. 主/ UI線程只允許讀取時間。
  3. 您仍然必須使用系統時間函數,因爲線程休眠函數的準確性不可信(取決於系統活動,線程的更新循環可能在您請求運行後幾毫秒內纔會運行)。

如果你像那樣實現它,那麼你甚至不需要熟悉互斥體就可以安全地啓動並運行線程,並且你的時間將是準確的。

但是!這裏有一些需要思考的食物:如果你想在一天的特定時間綁定遊戲觸發器,該怎麼辦?例如,將發送給用戶的消息「太陽已設置」或類似。無論如何,需要這樣做的代碼需要在主線程上運行(除非要實現跨線程消息通信隊列!),並且可能看起來像基本的定期檢查和更新時鐘代碼。所以在那一點上,你最好保持一個簡單的統一線程模型。

+0

不知道我最後的評論是否經過o.O.無論如何,如果它沒有:我是相當新的編碼(只需要爲java,C++和彙編幾個類),所以它會花一點時間讓我理解你的意思。感謝您的快速回答:) – 2013-02-25 05:05:45

+0

在您的回答中,您說時鐘線程是唯一能夠操控時間的線程。但id需要我的球員能夠休息。有沒有辦法讓我的主線程發出信號通知我的時鐘線前進若干小時? – 2013-02-25 05:11:55

+0

爲此,您可以:1.做一個完整的互斥體排除設計,2.掛起時鐘線程,3.向消息隊列發送時鐘線程的時鐘重置請求。我已經按他們所代表的難度順序(1是最簡單的)列出了它們。請記住,對於每1000毫秒只「執行一些操作」的線程,99%的時間很可能仍然可以正常工作。所以可能你永遠不會知道你是否做得對。 – jstine 2013-02-25 15:48:25

0

我通常使用一個名爲Simulation的類來前進時間。我沒有使用C++,但是我已經在Java中進行了線程化,這可以加快時間並根據時間表(或計劃時間的隨機事件)激活事件。您可以將其轉化爲C++或用於查看面向對象的實現是如何實現的。

package adventure; 

public class Simulation extends Thread { 

    private PriorityQueue prioQueue; 

    Simulation() { 
     prioQueue = new PriorityQueue(); 
     start(); 
    } 

    public void wakeMeAfter(Wakeable SleepingObject, double time) { 
     prioQueue.enqueue(SleepingObject, System.currentTimeMillis() + time); 
    } 

    public void run() { 
     while (true) { 
      try { 
       sleep(5); 

       if (prioQueue.getFirstTime() <= System.currentTimeMillis()) { 
        ((Wakeable) prioQueue.getFirst()).wakeup(); 
        prioQueue.dequeue(); 
       } 

      } catch (InterruptedException e) { 

      } 

     } 
    } 

} 

要使用它,你只需實例並添加你的對象:

`  Simulation sim = new Simulation(); 

     // Load images to be used as appearance-parameter for persons 
     Image studAppearance = loadPicture("Person.gif"); 

     // --- Add new persons here --- 
     new WalkingPerson(sim, this, "Peter", studAppearance); 
0

我會假設你的程序目前花費在等待用戶輸入其大部分的時間 - 這塊您的主線程不規則,並且時間相對較長,這會阻止您進行短時間更新。而你想避免複雜的解決方案(線程)。

如果您想訪問主線程中的時間,accessing it without a separate thread is relatively easy(請看示例)。

如果您在等待用戶輸入時不需要在後臺執行任何操作,您是否可以根據等待時已過的時間計算新值的函數?你可以有一些變量LastSystemTimeObserved,每當你需要使用一個你的時間依賴變量時,它就會被更新 - 調用一些函數來計算變量的變化值,這個函數根據上次被調用的時間過去了多少時間,而不是每次都重新計算一次值第二。

如果你確實做了一個單獨的線程,請確保你的線程都訪問了任何變量。