如何处理许多对象的定期更新?

时间:2011-11-09 22:23:06

标签: java coding-style timer

我正在开发一款小型Java游戏,依靠经典的小行星。

在这个游戏中,有大量的对象需要在特定的时间间隔内更新:

每一帧:移动或旋转的物体 每秒:游戏计时器 每隔几秒钟:敌人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,所以我不知道我的恐惧是否毫无根据,或者拥有这么多计时器是不是一个坏主意。

非常感谢您对此主题的建议,提示和更正!

2 个答案:

答案 0 :(得分:0)

我真的很喜欢你的设计,Updating界面抽象出实际需要更新的细节。当然你目前的实现并不是很优雅。也许你应该创建几个方法,如updateEveryFrame()updateEverySecond()等?每个对象只实现它需要工作的方法,而其他对象则是no-ops。

Timer实际上是一个不错的选择as well

  

这个类可以扩展到大量并发计划的任务(数千个应该没有问题)

但我建议将allObjectsThatNeedPeriodicUpdates拆分为:allObjectsThatNeedUpdateEveryFrameallObjectsThatNeedUpdateEverySecond等。为第一次收集创建一个周期性任务,为另一个创建另一个(具有不同的间隔)。

答案 1 :(得分:0)

你的方法看起来很好,这就是半条命所做的。唯一的区别是Half-Life(包括你的其他许多人)真正向更新功能发送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等。但这不是必需的。