我正在开发一款小型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,所以我不知道我的恐惧是否毫无根据,或者拥有这么多计时器是不是一个坏主意。
非常感谢您对此主题的建议,提示和更正!
答案 0 :(得分:0)
我真的很喜欢你的设计,Updating
界面抽象出实际需要更新的细节。当然你目前的实现并不是很优雅。也许你应该创建几个方法,如updateEveryFrame()
,updateEverySecond()
等?每个对象只实现它需要工作的方法,而其他对象则是no-ops。
Timer
实际上是一个不错的选择as well:
这个类可以扩展到大量并发计划的任务(数千个应该没有问题)
但我建议将allObjectsThatNeedPeriodicUpdates
拆分为:allObjectsThatNeedUpdateEveryFrame
,allObjectsThatNeedUpdateEverySecond
等。为第一次收集创建一个周期性任务,为另一个创建另一个(具有不同的间隔)。
答案 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;
}
}
如果您需要/需要,使用这样的增量时间可以更改更新间隔。是的,你可以并且将会有一堆计数器来跟踪各种游戏内事件。
我也可以将deltaTime
和timeUntilNewEnemySpawns
更改为等效于TimeSpan
的java,以便您可以访问一些有用的方法,如TotalSeconds等。但这不是必需的。