[英]Full-screen frame-rate limit conundrum
我的游戲(框架)在全屏狀態下的運行速度不能超過每秒30幀(兩次更新調用之間約33毫秒)。 我使用一個計時器循環。 實際上,它變得有點復雜,因為當我逐漸減少延遲時,我測量的兩次呼叫之間的時間就變得很瘋狂。 它從設置的延遲跳到期望值的兩倍或更多。 該閾值似乎是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()上,而全畫幅繪制在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;
}
知道為什么模式的行為不同嗎? (除了幀速率和一些潛在的內存泄漏,該程序運行平穩。)
從理論上講,計時器的周期不能短於渲染一幀所花費的時間。 實際上,它需要更長的時間,否則您將立即飽和計時器的共享線程。 您需要進行個人資料確定。 即使沒有縮放比例,對drawImage()
調用通常仍占主導地位。 此AnimationTest
顯示最后幾個FRAMES
的渲染時間的移動平均值。 您可以使用該方法來調整實現,以適應最慢的可接受目標平台。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.