在Java游戏循环中使用“ SwingUtilities.invokeLater()”是一种不好的做法吗?
作者:互联网
因此,我正在用JAVA创建一个等距游戏;简而言之,它有一个由图块组成的地图,当用户在屏幕上拖动鼠标时,地图就会移动.为了给大家一个主意,目前看起来像这样:
在实际的原型版本之前,我构建了一个小的Java应用程序,该应用程序本身没有“ Game Loop”.唯一更新平铺地图位置的事件是鼠标拖动的事件侦听器,并且在移动更新后调用了repaint()方法.它工作正常,我可以选择“图块”并移动地图而不会出现问题.
从那时起,我用游戏状态管理器和真实的游戏循环来重建原型思维,以开发更像真实游戏引擎的东西.游戏循环代码如下所示:
init();
long start;
long elapsed;
long wait;
while(running){
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0)wait = 5;
try{
Thread.sleep(wait);
} catch(Exception e) {
e.printStackTrace();
}
}
GameStateManager需要使用update()和draw()方法,因此我可以像较旧的原型一样绘制地图.当我在屏幕上拖动鼠标以便地图可以移动时,发生了问题.在我可以实际看到所有瓷砖最终位置之前的瓷砖之间移动的黑色背景的范围内,该动画变得非常怪异.
起初,我认为问题出在Game Loop线程和主类的事件侦听器之间并发,因为可以在JPanel试图绘制地图时调用mouseDragged事件.然后我在游戏循环代码中对此进行了测试:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
draw();
drawToScreen();
}
});
//draw();
//drawToScreen();
现在,原型工作正常.
因此,我的问题是,这种性能是否很沉重,或者只是Java中的不良做法?另外,我的“并发”假设正确吗?这是我第一次使用Java处理线程,所以我真的不知道我是否以正确的方式处理了这个问题.
obs:这是我制作的整个类,其中包含游戏循环:
http://pastebin.com/RMRHYc5X
obs2:如果有人感兴趣,我工作的游戏循环逻辑基于pj644制作的youtube java教程,名为“ Java 2D Game Programming”.
obs3:对不起,如果问题太大,这是我第一次在此网站上发布问题!
解决方法:
Swing并不是真正的写游戏技术,它更新缓慢并且在很多方面受到限制.
话虽如此,当您的游戏线程完成工作时,调用invokeLater或使用SwingWorker是更新屏幕的正确方法.
在进一步介绍之前,我确实建议您看一下2d或3d java图形和游戏框架.这样,您将能够获得更好的结果,并且将为您完成很多工作,包括设置游戏循环,更新,管理帧频等.
标签:game-loop,swing,java 来源: https://codeday.me/bug/20191029/1959103.html