2012-04-10 140 views
1

我有一個關於良好實踐的問題。我正在做一個簡單的遊戲,我正在搞一些精靈。1全面的定時器與多個定時器,每個對象的定時器

我有一個精靈類。在那個類中,有一個計時器每隔幾毫秒運行一次。

現在,我有一個List<Creatures>和「生物」的每個人,都有一個Sprite對象來運行動畫。這意味着每個生物都有一個計時器來完成同樣的事情。

我決定改變它,並且創建一個只在列表上迭代的計時器,並調用爲每個「Creature」創建動畫的函數。

什麼是好習慣?

  1. 給每個「生物」自己的計時器。
  2. 在迭代列表的Form中創建一個「大」定時器,並調用每個對象創建動畫的函數。
  3. 一種不同的方式

回答

5

我有一個精靈類。在那個類中,有一個計時器每隔幾毫秒運行一次。

不幸的是,它並沒有在現實中。您受限於(非高性能)系統時鐘的分辨率,該時鐘在〜15  毫秒附近。所以,如果你喜歡,你可以設置1的間隔,但這不是你實際得到的。

回到主題,對於遊戲,所有內容都應該在同一個時鐘上運行。對於每個勾號,您將有一個循環來更新遊戲的邏輯狀態(位置和內容),然後顯示(動畫幀,屏幕上的blit等)。如果您在不同的定時器上使用它們,您將很可能遇到問題,因爲在並行更新對象時協調對象的狀態會變得非常困難。

還意識到您需要規範化更新速率以確保事情不會更新得太快或太慢(取決於您渲染幀需要多長時間)。您需要檢查上次更新和新更新之間的差異,並採取相應措施。

5

如果它們以相同的間隔都運行,一個大的定時器肯定是要走的路。

即使它們運行在不同的時間間隔,一個大計時器(具有確定哪些子處理程序觸發的邏輯)通常仍然是最好的。

某些庫會在內部添加此邏輯,並且只從操作系統請求一個定時器。你還沒有確切地說過你正在使用哪個計時器(.NET至少有四個),所以我建議你自己使用一個集中計時器。

+0

即時通訊使用System.Windows.Forms.Timer – samy 2012-04-10 21:18:19

+0

@samy:意識到此計時器在UI線程上運行'Tick'事件委託。 – 2012-04-10 21:19:18

1

最好的辦法是實現一個遊戲循環,記錄自上次循環迭代以來已經過了多少時間,然後將經過的時間量傳遞給所有需要更新自身的實體。

例如,OpenTk實現several events,其在每次通過遊戲循環(例如,OnUpdateFrame,OnRenderFrame)時發生。

這些事件的

每個傳遞FrameEventArgs類型的參數,它具有時間的一個屬性:

/// <summary> 
/// Gets a <see cref="System.Double"/> that indicates how many seconds of time elapsed since the previous event. 
/// </summary> 
public double Time 
{ 
    get { return elapsed; } 
    internal set 
    { 
     if (value <= 0) 
      throw new ArgumentOutOfRangeException(); 
     elapsed = value; 
    } 
} 

基於經過的時間,你就可以找出動畫幀在精靈渲染。

增加的好處是,通過查看這段時間,您可以計算出您當前正在運行的每秒多少幀,並基於此決定(跳過幀的渲染,降低渲染複雜度等) 。