2011-11-09 23 views
3

我正在研究一個小小的Java遊戲,靠着經典的小行星。如何處理許多對象的定期更新?

在這個遊戲中有一噸,其需要在一定的時間間隔進行更新的對象:

每一幀:Objects的移動或旋轉。
每秒鐘:遊戲計時器。
每隔幾秒鐘:敵人AI,敵人產卵
每隔幾秒鐘:從艦船武器中發射一顆新子彈。

目前我處理這樣的:

//This method is called by a timer that is run every 30 milliseconds 
//It will iterate through all objects that require periodic updates and call their 
//update method every 30ms. 
public void frameUpdateLoop(){ 
    for(Updating u : allObjectsThatNeedPeriodicUpdates){ 
     u.update(); 
    } 
} 

public class EnemySpawner implements Updating{ 
    private static final int SPAWN_TRESHOLD=500; 
    private int timeUntilNewEnemySpawns=SPAWN_TRESHOLD; 

    //This method is called by frameUpdateLoop() 
    //It is only supposed to do work once every 500ms, but is called every 
    //30ms nonetheless. 
    public void update(){ 
     timeUntilNewEnemySpawns -= 30; //Subtract time since last update 
     if(timeUntilNewEnemySpawns <= 0){ 
      SpawnNewEnemy(); 
      timeUntilNewEnemySpawns = SPAWN_TRESHOLD; 
     } 
    } 
} 

當然,這僅僅是我如何使用它的一個例子,所以我刪除不必要的部分。

我的問題是: 這是實現這樣一個更新系統的權利(=一種好方法)嗎? 在閱讀時,我注意到大部分時間都是用Timer來完成這樣的任務。

但是,這將需要我一次運行數十個計時器(每個需要更新的對象一個)。
如果我理解正確,Timer的每個實例也會創建一個新線程,所以我擔心這會在某個時候成爲問題(線程處理性能損失超過我的當前系統 - 或線程數量變得太大)。

我對Java很陌生,所以我不知道我的擔心是沒有根據的,或者如果確實有這麼多定時器是一個壞主意。

非常感謝您對此主題的建議,提示和更正!

回答

0

我真的很喜歡你的設計與Updating接口抽象實際上有什麼更新的細節。當然你現在的實現不是很優雅。也許你應該創建幾種方法,如updateEveryFrame(),updateEverySecond()等?每個對象只實現它需要工作的方法,而讓其他對象停止工作。

Timer實際上是一個很好的選擇在這裏as well

這個類擴展到大量同時安排的任務(千應該不會出現什麼問題)

不過,我會建議分裂allObjectsThatNeedPeriodicUpdates到: allObjectsThatNeedUpdateEveryFrame,allObjectsThatNeedUpdateEverySecond等。爲第一次收集創建一個週期性任務,爲另一個創建另一個(不同間隔)。

0

你的方法看起來不錯,這是半條命的做法。唯一的區別是半條命(包括你自己的許多其他條款)會向Delta函數發送一個Delta Time,這樣你就不必爲每個更新函數硬編碼30ms。所以:

public void update(int deltaTime){ 
    timeUntilNewEnemySpawns -= deltaTime; //Subtract the delta time 
    if(timeUntilNewEnemySpawns <= 0){ 
     SpawnNewEnemy(); 
     timeUntilNewEnemySpawns = SPAWN_TRESHOLD; 
    } 
} 

使用這樣的增量時間將允許您更改更新間隔,如果您曾經想要/需要。是的,你可以並且會有一堆計數器來跟蹤各種遊戲中的事件。

我也可能將deltaTimetimeUntilNewEnemySpawns更改爲與TimeSpan等效的java,以便您可以訪問一些有用的方法,如TotalSeconds等。但這並不是必需的。

+0

傳遞deltaTime也是一個好主意,因爲幀渲染可能需要幾毫秒才能完成,您的物理方程需要知道已經過了多少時間。在一個緩慢的時期,讓他們花更長時間的跳躍等等。 – Karl

+0

@Karl,在很多情況下都是如此,但是關於固定與可變時間步長的大量討論值得一讀:http://gamedev.stackexchange。 COM /問題/ 1589 /固定時間步VS-可變時間步 –