使用第二个线程为Java游戏生成数据

时间:2014-06-08 22:45:35

标签: java multithreading loops

我正在用Java创建一个体素游戏。目前,我使用perlin噪声生成包含在HashMap中的3d块(16x16x16短阵列)的数据。一切正常。当玩家移动时,我想在玩家附近渲染块(现在,在任何方向上都有5个块)。如果一个块不存在,它应该生成它。

问题在于生成一个块需要大约半秒钟,所以当玩家离开生成的区域时,游戏循环冻结几秒钟,同时生成必要的块然后恢复。

我正在使用lwjgl进行OpenGL,我的游戏循环看起来像这样:

while (!Display.isCloseRequested()){
    update(); //my update method
    render(); //my render method
    Display.update(); //refresh the screen
    Display.sync(60); //sync to 60 fps
}

我尝试使用第二个线程在更新和渲染时生成数据,但未成功但我无法弄清楚如何在不冻结游戏循环的情况下执行此操作。我认为应该有一种方法可以在第二个线程中对块进行排队,然后在短时间内运行该线程,但我对Java中的多线程几乎没有任何经验,所以对此有任何帮助都会受到赞赏。

3 个答案:

答案 0 :(得分:0)

如果玩家可以看到他周围的五个块,你可以在进入一个方向之前在六行之外生成块。这样您就可以尽早完成工作,并可以直接显示块。 这个生成块的任务可以在单独的线程中完成。它不必在游戏循环中调用。你必须在进入游戏循环之前调用generater-thread。

答案 1 :(得分:0)

我有一个后台线程,当玩家移动时会通知他,然后预生成与玩家移动位置相邻的块。它由优先级队列支持,以便从未访问过的单元格的积压不在队列的顶部,并且旧的队列条目在与玩家相距一定距离后被删除。 / p>

利用线程的关键是你在玩家移动之前生成块,并减少移动时间以生成块,以及可能不需要的块。

最重要的警告:如果你把所有代都卸载到那个线程,那么你将需要使用Futures,这样你就可以获得生成的块。

答案 2 :(得分:0)

好的,我只使用一个线程解决了我的问题。我创建了一个TaskManager,负责持有要完成的任务的arraylist。因此,每次我需要生成一个块时,我都会传递一个包含信息的任务对象来实际执行任务。然后,每次更新,我都会调用TaskManager.next()来执行下一个任务。

现在,它不是在一次冻结帧速率的更新中生成49个新块,而是在每次更新时生成一个块,直到它们全部生成为止。