低计算java paintcomponent中的低fps

时间:2012-03-12 17:44:43

标签: java performance graphics2d paintcomponent

我正在制作一个游戏,为了这个问题的目的,我有一个扩展JFrame的类,它增加了一个扩展JPanel(GamePanel)的类。在GamePanel中我有一个run方法,它有两个函数update();和重绘();然后是Thread.sleep(20)。更新功能大约需要1-2ms。我在paintComponent(Graphics g)中拥有所有绘图内容,当我使用repaint()时似乎正确调用,因为东西显示在屏幕上。

我的问题是,它是不可思议的迟滞。当我没有Thread.sleep(20)时,它就像2fps一样无法播放。我读到这是因为repaint()没有足够的时间来完成或者其他什么所以我在下一个循环之前添加了一个延迟。任何高于或低于20毫秒的东西似乎都会让它变得更加迟钝。

我尝试过使用图形配置,双缓冲等等但是它仍然很滞后。在我的家用电脑,这是一个英特尔i5,四核,3.2GHz我只有大约100fps,在学校的电脑上我得到大约15fps(好的电脑,像我认为的amd双核心)。 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!

3 个答案:

答案 0 :(得分:4)

不假装是最终解决方案,只是一些提示:

  1. 确保您的缓冲图像与其绘制的默认值GraphicsDevice具有相同的颜色模型。方法GraphicsConfiguration.createCompatibleImage可以创建此类图像。

  2. 如果可能的话,尝试将整个巨大的地图拆分为图块并跳过屏幕外(游戏视图外)部分。

  3. 您提到使用被动呈现,就像您提到的repaint()一样。事件调度线程用于Swing和AWT中的许多事情,并且它不能保证主动渲染游戏的可接受时间。也许值得重新设计渲染部分游戏以使用Active Rendering。可以找到教程和示例here

答案 1 :(得分:0)

嗯,对于游戏开发我不认为在Swing中绘制一个巨大的图像组件将会赢得任何速度记录。 100 FPS仍然令人惊叹(比大多数LCD显示器的刷新率高出约40 FPS)。

为了提高速度,您正在使用的绘图基元必须加速。在你的学校电脑上,他们可能只是缺少一个像样的显卡来提供所需的2D加速(这些PC如何在浏览器和绘画程序中进行正常的2D操作?)

您可能希望查看使用OpenGL的框架,例如JOGL。另一种选择是试用JavaFX 2 - 它可能有更好的渲染管道。

答案 2 :(得分:0)

我也正在开发一个Java游戏并做了很多与你相同的事情(扩展JPanel并调用repaint())。一个区别是我使用javax.swing.Timer来调用ActionPerformed(ActionEvent e)方法来每5ms更新一次我的游戏。在方法结束时,它调用repaint()来进行渲染。

此外,如果您使用Graphics2D进行渲染,您可以使用RenderingHints指导计算机如何渲染您的游戏(例如,速度或质量,等等)。

我没有完全测量FPS但是我的Ubuntu 12.10系统没有延迟,而且在Windows 8上只是慢一点。

如果我的回答不完全符合您的要求,我会道歉,但到目前为止,这对我来说没有问题。