我正在用Java制作一个炸弹人游戏,游戏似乎正在减缓PC超载处理器和CPU的速度。我在另一个游戏中使用了循环,它工作正常,没有造成任何性能问题。但是我确实注意到只需注释掉gameloop()就会导致重大的性能问题
游戏循环我使用:
public void start() {
window.setVisible(true);
running = true;
int fps = 60;
double timePerTick = 1e9 / fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
while (running) {
now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
lastTime = now;
if (delta >= 1) {
gameLoop(); /* commenting this out will cause major performance
* problem to the PC */
delta--;
}
}
}
@Override
public void gameLoop() {
if(!gameover){
run();
gui.repaint();
}
}
这个循环是否有任何问题可能导致问题,或者是否有更好的方法可以减少性能问题
[编辑] 我改变循环以使用计时器执行类似的任务,它工作正常并且不会导致任何性能问题,此方法的任何问题仍然存在(长期问题)?
public void start(int fps){
window.setVisible(true);
running = true;
gameTimer.scheduleAtFixedRate(new GameTimer(), 0, 1000/fps);
}
private class GameTimer extends TimerTask{
@Override
public void run(){
gameLoop();
}
}
答案 0 :(得分:1)
您正在进行无限循环而没有任何暂停消耗100%的CPU,在您的情况下根据您的需要,您应该定义您的帧速率并设置相应的睡眠时间,如下所示:
run();
gui.repaint();
// Make the current thread sleeps 1 000 milliseconds which means 1 frame per sec
Thread.sleep(1000L);
答案 1 :(得分:0)
您正在忙着循环,这将使一个线程永久忙碌。这不可避免地会占用CPU资源,减少对其他任何东西的可用性。
当有足够的时间过去时,你应该预测,而不是经常使用nanoTime()并调用gameloop(),此时下一次调用gameloop()将会发生并调用Thread.sleep ()暂停线程直到到达时间。出于许多目的,它的准确性足以计算下一个滴答到期时的毫秒时间戳,减去当前时间并睡眠该量:
long lastTick = System.currentTimeMillis();
long ticksPerFrame = 1000 / fps;
while (true) {
long nextTick = lastTick + ticksPerFrame;
long sleep = nextTick - System.currentTimeMillis();
if (sleep > 0) {
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
lastTick = nextTick;
gameloop();
}
(未经过测试的代码,仅用于演示一般方法)
这将仅与系统计时器分辨率加/减睡眠变化一样准确。对于大多数系统而言,这意味着平均几毫秒的变化,对于许多场景都是可接受的,特别是如果你使用AWT / Swing进行渲染的话。如果你以比EDT处理它们更快的速度放置repaint()调用,可以跳过重绘,这在大多数情况下是可取的,因为它允许重绘队列在延迟时赶上。