我的游戏(框架)在全屏幕上的速度不能超过每秒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);
}
这是我的图形(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()和fulls-creen上绘制 graphicDevice.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;
}
知道为什么模式的不同行为? (除了帧速率和一些潜在的内存泄漏,程序运行顺利。)
答案 0 :(得分:1)
理论上,计时器的周期不能短于渲染一帧所用的时间。实际上,它需要更长时间,否则您将立即使计时器的共享线程饱和。您需要profile才能确定。即使没有缩放,对drawImage()
的呼叫通常也占主导地位。此AnimationTest
显示最近几个FRAMES
的渲染时间的移动平均值。您可以使用该方法调整实施以适应最慢的可接受目标平台。