非常高的CPU使用率,具有简单的Java游戏循环
我一直在学习游戏设计的原则,并在许多教程的帮助下用Java制作了这个游戏循环。它现在所做的只是在JFrame上渲染草平铺:非常高的CPU使用率,具有简单的Java游戏循环,java,cpu,Java,Cpu,我一直在学习游戏设计的原则,并在许多教程的帮助下用Java制作了这个游戏循环。它现在所做的只是在JFrame上渲染草平铺: public class Game extends JPanel implements Runnable { String title; int height; int width; boolean ps; private int ticks; private JPanel p; private BufferStrategy bs; private Graphic
public class Game extends JPanel implements Runnable {
String title;
int height;
int width;
boolean ps;
private int ticks;
private JPanel p;
private BufferStrategy bs;
private Graphics g;
private boolean running = false;
private Thread thread;
private Frame frame;
private KeyHandler keyHandler;
public Game(String title, int width, int height){
this.width = width;
this.height = height;
this.title = title;
keyHandler = new KeyHandler();
}
private void init() {
TileHandler.init();
frame = new Frame(title, height, width);
frame.getFrame().addKeyListener(keyHandler);
}
private void tick() {
// KeyHandler.tick();
// updates game logic
}
private void render() {
render(g);
}
private void render (Graphics g) {
bs = frame.getCanvas().getBufferStrategy();
if(bs == null){
frame.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.clearRect(0, 0, width, height);
g.drawImage(TileHandler.grass, keyHandler.getPlayerX(),
keyHandler.getPlayerY(), null);
bs.show();
g.dispose();
}
@Override
public void run() {
int x = 4;
init();
int fps = 60; // target
double tickTime = 1000000000 / fps; // time per 1 frame
double delta = 0;
long timer = 0;
long startTime = System.nanoTime();
long endTime;
while (x == 4) {
endTime = System.nanoTime();
delta += (endTime - startTime) / tickTime;
timer += endTime - startTime;
startTime = endTime;
if (delta >= 1) {
ticks++;
render();
delta--;
}
if(timer >= 1000000000){
ticks = 0;
timer = 0;
}
}
}
public int getTicks() {
return ticks;
}
public synchronized void startThread() {
// Start the thread
if (!running) { // if not already
running, you can begin
running = true;
thread = new Thread(this); //Run THIS class on a
new thread
thread.start();
}
else { // safety measure
return;
}
}
public void stopThread() {
if (!running) {
return;
}
running = false;
try {
thread.join(); //Method stops the thread
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
它工作得很好,我可以让它以稳定的每秒60帧的速度运行,唯一的问题是它占用了太多的CPU。平均而言,它使用了大约50%的CPU,并降低了我电脑的其他部分的速度——Minecraft在我的笔记本电脑上也使用了同样的速度!我知道问题在于上面代码中的游戏循环
所以我只是想了解是什么导致了这一切。我确实尝试使用探查器,但仍然无法找出问题的原因。请给出最简单的答案:您的循环正在以CPU能够处理的速度运行。我假设您有一个具有两个内核的CPU,因此主循环线程正在使用它可以获得的每一点计算能力,以尽可能快地运行循环,从而阻塞两个内核中的一个(50%) 一种解决方案是计算每次迭代所需的时间,并在下一次迭代开始之前睡眠一段时间。下面是一个伪代码:
while(running) {
long startTime = getTime();
update();
render();
long endTime = getTime();
long elapsedTime = endTime - startTime;
Thread.sleep(TARGET_FRAME_TIME - elapsedTime); //sleep to yield unneeded CPU usage
}
此外,如果您没有使用像LWJGL或JOGL这样的OpenGL库,那么swing的性能也不会很好。我不知道你的游戏会是什么,但60fps可能是swing的上限
我建议您学习JavaFX for games,因为它使用硬件加速进行渲染,并且对于相对复杂的应用程序可以处理120fps+的速度。它还为游戏循环设计提供和类。循环不断运行,以查看是否需要调用render()。这叫做轮询,通常是个坏主意。试着用一个定时器来调用render(),我也建议你研究一下JavaFX,因为它使用硬件加速,更适合游戏开发。它还附带了像和这样的类,使gameloop管理变得非常简单。+1,但是Swing有时仍然会阻止渲染过程,因为这种情况不再发生。谢谢大家的建议,我比以前更了解现在发生的事情。看来2D游戏库是前进的方向!如果您想继续使用标准库,请查看JavaFX。它是完美的2D游戏,当你不想去第三方。(我可能是个小粉丝)