我的游戏(框架)在全屏时不能超过每秒 30 帧(更新调用之间大约 33 毫秒)。我使用 Timer 进行循环。实际上它变得有点复杂,因为当我逐渐减少延迟时,我测量的调用之间的时间变得疯狂。它从设定的延迟跳到预期值的两倍或更多。阈值似乎是 30 毫秒。在窗口模式下没有问题,在 4 ms 阈值处开始出现差异。两种模式都以较高的延迟正常运行。以下是我认为相关的部分代码。
fps = 30;
timer = new Timer(1000/fps, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
tick();
}
以上是定时器设置。下面是其余的。
private void tick(){
update(gameTime);
draw(gameTime);
}
这是我的 Graphics(2D) 和 BufferedImage。
public DrawBatch(DeviceManager deviceManager) {
this.deviceManager = deviceManager;
color = Color.MAGENTA;
bufferedImage = deviceManager.getBufferedImage();
bufferedGraphics = (Graphics2D)bufferedImage.getGraphics();bufferedGraphics = (Graphics2D)bufferedImage.getGraphics();
bufferedGraphics.setBackground(color);
bufferedGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
bufferedGraphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
bufferedGraphics.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
draw(GameTime gameTime) 方法从这个方法开始:
public void begin(){
bufferedGraphics.clearRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
}
现在我们可以使用 bufferedGraphics 进行绘制了。draw(GT gT) 以此结束。(灵感来自 xna)
public void end(){
if(deviceManager.isFullScreen())deviceManager.getGraphics().drawImage(bufferedImage, 0,0, null);
else deviceManager.getGraphics().drawImage(bufferedImage, 3,25, null);
deviceManager.getGraphics().dispose();
bufferedImage.flush();
}
我回收了相同的 BufferedImage,因为制作新的(连同 Graphics 对象)造成了内存泄漏。不知道是否使用相同的 Graphics 对象而不是每帧执行 .dispose() / new Graphics。
在窗口模式下,BufferedImage 在 jFrame.getGraphics() 上绘制,在 graphicsDevice.getFullScreenWindow().getGraphics() 上以全屏形式绘制。
这是全屏设置。
public void setFS(){
jFrame.setVisible(false);
jFrame.dispose();
jFrame.setIgnoreRepaint(true);
jFrame.setResizable(false);
jFrame.setUndecorated(true);
graphicDevice.setFullScreenWindow(jFrame);
graphicDevice.getFullScreenWindow().setIgnoreRepaint(true);
graphicDevice.setDisplayMode(new DisplayMode(width, height, 32, 60));
jFrame.setVisible(true);
fullScreen = true;
}
和窗口设置。
public void setW(){
jFrame.setVisible(false);
jFrame.dispose();
jFrame.setIgnoreRepaint(true);
jFrame.setResizable(false);
jFrame.setUndecorated(false);
graphicDevice.setFullScreenWindow(null);
jFrame.setSize(width, height);
jFrame.setVisible(true);
jFrame.getContentPane().setPreferredSize(new Dimension(800, 600));
jFrame.pack();
fullScreen = false;
}
知道为什么模式的不同行为吗?(除了帧率和一些潜在的内存泄漏,程序运行平稳。)