我正在做一个游戏,出于这个问题的目的,我有一个扩展JFrame的类,它添加了一个扩展JPanel(GamePanel)的类。在GamePanel中,我有一个run方法,它有两个函数update();和repaint();,然后是一个Thread.sleep(20)。更新功能大约需要1-2ms。我的所有绘图内容都在paintComponent(Graphics g)中,当我使用repaint()时,似乎可以正确地调用它,因为这些内容会显示在屏幕上。
我的问题是,它的滞后程度令人难以置信。当我没有Thread.sleep(20)时,它不能以2fps播放。我读到这是因为repaint()没有足够的时间来完成,或者其他什么,所以我在下一次循环之前添加了一个延迟。任何高于或低于20毫秒的时间似乎都会使它变得更加滞后。
我尝试过使用图形配置、双缓冲和更多,但它仍然很慢。在我的家用电脑上,这是一台英特尔的i5,四核,3.2 get,我只能达到100fps左右,而在学校的电脑上,我可以达到15fps (还可以,我相信是双核电脑)。paintComponent循环是超级轻量级的!只需绘制偏移量取决于球员的位置,然后在屏幕中间绘制球员!我用的是2000x2000,0.8mb的地图。已尝试切换到1000x1000 0.4mb,没有差别。
代码如下:
@Override
public void paintComponent(Graphics g) {
//Rendering settings and stuff
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//Draw map gameMap.gameMap is a bufferedImage
g2d.drawImage(gameMap.gameMap, gameMap.x, gameMap.y, null);
//Draw health bar
g2d.setColor(healthBarColor);
g2d.setComposite(alphaHealthBarBackground);
g2d.fillRect(100, 19, 200, 23);
g2d.setFont(font);
g2d.setComposite(alphaNormal);
g2d.setColor(healthBarColor);
g2d.drawString("HP: ", 20, 40);
g2d.fillRect(100, 19, player.health * 2, 23);
//Draw player player.playerImage is a BufferedImage
rotatePlayer.setToRotation(rotation, rotationAnchor.x, rotationAnchor.y);
rotatePlayer.translate(xResolution / 2, yResolution / 2);
g2d.drawImage(player.playerImage, rotatePlayer, this);
g2d.setColor(Color.white);
}这导致了在相对很棒的计算机上100fps和下降计算机上的15fps!
发布于 2012-03-13 02:53:46
不是假装是最终的解决方案,只是一些提示:
GraphicsDevice的默认颜色模型相同。方法GraphicsConfiguration.createCompatibleImage可以创建这样的图像。repaint()。Event Dispatch Thread用于Swing和AWT中的许多事情,它不能保证主动渲染游戏的可接受计时。也许重新设计游戏的渲染部分以使用活动渲染是值得的。教程和示例可以在here.上找到
发布于 2012-03-13 02:50:28
嗯,对于游戏开发,我不认为在Swing paintComponent中绘制一个巨大的图像会赢得任何速度记录。100FPS仍然令人惊叹(比大多数LCD显示器的刷新率高出约40FPS)。
要获得更快的速度,必须对正在使用的绘图基元进行加速。在你学校的电脑上,他们可能只是缺少一个像样的图形卡来提供所需的2D加速(这些电脑在浏览器和绘画程序中进行正常的2D操作感觉如何?)
您可能希望研究一下使用OpenGL的框架,比如JOGL。另一种选择是尝试JavaFX 2 --它可能具有更好的呈现管道。
发布于 2014-07-05 12:50:31
我还在开发一个Java游戏,并且已经做了很多和您一样的事情(扩展JPanel并调用repaint())。一个不同之处在于,我使用javax.swing.Timer调用ActionPerformed(ActionEvent e)方法,每隔5ms更新一次游戏。在方法的末尾,它调用repaint()来进行渲染。
此外,如果你正在使用Graphics2D进行渲染,你可以使用RenderingHints来指导计算机如何渲染你的游戏(例如,速度或质量,诸如此类)。
我没有准确测量FPS,但我在Ubuntu 12.10系统上没有延迟,在Windows8上只慢了一点。
如果我的回答不完全是你想要的,我道歉,但这就是到目前为止对我有效的方法,没有问题。
https://stackoverflow.com/questions/9672088
复制相似问题