Java小程序,游戏循环第一次运行正常,然后在重置时以一半的速度更新
因此,对于我正在创建的游戏,我意识到我的gameLoop有问题,因为我第一次玩游戏时,它运行得很好,但第二次或之后的任何时候,它都会减慢一半左右。即使我最小化游戏(因为这会停止gameLoop,然后再次启动它会启动它),gameLoop代码如下:Java小程序,游戏循环第一次运行正常,然后在重置时以一半的速度更新,java,multithreading,applet,Java,Multithreading,Applet,因此,对于我正在创建的游戏,我意识到我的gameLoop有问题,因为我第一次玩游戏时,它运行得很好,但第二次或之后的任何时候,它都会减慢一半左右。即使我最小化游戏(因为这会停止gameLoop,然后再次启动它会启动它),gameLoop代码如下: public void gameLoop(){ new Thread(){ public void run() { while(gameRunning){
public void gameLoop(){
new Thread(){
public void run() {
while(gameRunning){
try {
Thread.sleep(1000/60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (tutorial){
updateBullet();
updatePlayer();
repaint();
} else {
updateEnemies();
updateBullet();
createEnemies();
updateParticles();
updatePlayer();
repaint();
}
}
repaint();
}
}.start();
}
我第一次在init()中用
gameLoop();
我还有:
public void stop(){
bg.stop();
gameRunning = false;
}
public void start(){
bg.start();
gameRunning = true;
gameLoop();
}
最后,playerUpdate还会停止循环(玩家内部的线程是为了在玩家死亡后完成一些效果):
那么,为什么每次循环停止并再次启动时,它都以一半的速度运行呢?谢谢 看起来您正在为每个gameloop启动一个新线程;这意味着每次gameloop运行时,您都有另一个线程供JavaVM处理。这是非常低效的,因为最终会有1000个线程运行,造成巨大的延迟。有没有什么方法可以不用线程来重写代码 还有,这应该做什么
try {
Thread.sleep(1000/60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
你为什么要做1000/60?A:为什么不用16呢?B:看来你在这里有别的意思,但不确定是什么意思
另外,您在
start()
和stop()
方法中引用的bg变量是什么?看起来您正试图使用gameRunning布尔值来停止线程。如果这不是易变的,那么游戏循环可能不会注意到GUI线程将其设置为false并将永远运行的更改。即使它是易变的,如果在游戏线程注意到stop命令之前再次调用start,您也会遇到竞争条件
相反,您应该在创建的线程中存储一个引用,并在stop方法中中断它
另外,您的所有更新方法相对于paint方法都是线程安全的。updatePlayer看起来不是线程安全的,而且您不知道何时调用paint,因此它可能与您的更新方法同时发生。即使paint方法不写入共享数据,它仍然可以看到由于缺少内存屏障而不一致的数据
我建议在GUI线程中执行所有更新,除非它非常慢并且需要多线程。看看如何使用Swing中的计时器来启动更新逻辑。1000/60计算循环每秒处理60次的时间量。换句话说,每秒60帧。还有其他方法可以实现这一点,更不用说处理游戏所需的时间也不算在内。bg是循环的背景声音,我正在停止和启动它,如果这是一种不好的方法,还有什么更好的方法?我正在使用的这本书谈到了你如何需要一个gameloop什么是更好的方法?那家伙是对的,每秒60帧。“有没有一种方法可以让我停止线程,然后开始一个新的线程?”JeremySayers抱歉,我以为你在试图用睡眠做其他事情。至于线程,仍然不确定我的想法是否正确,但gameLoop多久调用一次?它的名字意味着它将被重复called@JeremySayers使某些东西线程安全是复杂的,您可能应该阅读一些关于线程安全的教程。如果不需要,最简单的方法就是避免线程。有多种方法可以使某个线程安全,但归根结底,就是看线程在哪里可以交错,并检查如果语句按一定顺序运行,一个线程是否可以使另一个线程的假设无效。例如,在你的更新播放器中,你调用敌人.remove(),如果paint()在敌人中循环,当这种情况发生时,你会得到一个ConcurrentModificationException。
if (!gameRunning){
if (arg0.getKeyCode() == KeyEvent.VK_ENTER){
enemies.clear();
bullets.clear();
particles.clear();
score = 0;
player.x = 200;
player.isMovingLeft = false;
player.isMovingRight = false;
player.isAlive = (true);
gameRunning = true;
gameLoop();
}
}
try {
Thread.sleep(1000/60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}