所以对于我正在创造的游戏,我意识到我的迷雾已经对我的gameLoop做了一些错误,因为我第一次玩我的游戏它运行得很好,但是第二次或之后的任何事情,它减慢了大约一半。即使我最小化游戏(因为它停止了游戏循环,然后再次启动它启动它备份)这里是gameLoop代码:
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也会停止循环(玩家内部的线程允许在玩家死后完成某些效果):
public void updatePlayer(){
if (player.isMovingLeft){
player.x-=3;
}
if (player.isMovingRight){
player.x+=3;
}
for (int j=0; j < enemies.size(); j++){
if (player.isAlive){
if (enemies.get(j).x+19 > player.x && enemies.get(j).x < player.x+40 && enemies.get(j).y > player.y && enemies.get(j).y < player.y+40) {
enemies.remove(j);
j--;
explode.setFramePosition(0);
explode.start();
for (int k = 0; k <21; k++){
addParticle(player.x+20,player.y+20,2);
}
new Thread(){
public void run() {
try {
Thread.sleep(2000);
gameRunning = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
player.isAlive = false;
break;
}
}
}
}
然后在keyPressed事件中重新启动:
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();
}
}
那么为什么每当循环停止并再次启动时,它以一半的速度运行?谢谢!
答案 0 :(得分:1)
看起来你正在为每个游戏循环开始一个新线程;这意味着每次游戏循环运行时,您都有另一个线程供Java VM处理。这是非常低效的,因为最终你将有1000个线程在运行,导致巨大的延迟。你有没有办法在没有线程的情况下重写你的代码?
此外,这应该做什么?
try {
Thread.sleep(1000/60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
你为什么要做1000/60?答:为什么不用16? B:看起来你在这里意味着什么,不知道是什么
此外,您的start()
和stop()
方法中的bg变量是什么?
答案 1 :(得分:0)
看起来你正试图通过使用gameRunning布尔来阻止线程。如果这不是易失性的,那么游戏循环可能不会注意到将GUI设置为false并将永远运行的GUI线程的更改。即使它是易失性的,如果在游戏线程注意到停止命令之前再次调用start,则会出现竞争条件。
您应该在创建的线程中存储引用并在stop方法中将其中断。
对于paint方法,所有更新方法都是线程安全的。 updatePlayer看起来不是线程安全的,并且您不知道何时调用paint,因此它可能与更新方法同时发生。即使paint方法没有写入共享数据,由于缺少内存屏障,它仍然可能会看到不一致的数据。
我建议在GUI线程中进行所有更新,除非它非常慢并且您需要多线程。看看使用Swing中的Timer来启动更新逻辑。