简单的Java2D应用程序中的可怕性能

时间:2009-04-20 15:50:03

标签: java performance java-2d

我刚刚参加了第14届Ludum Dare 48小时游戏制作比赛my entry,并决定在java中使用java2d进行图形处理。

我对API并不熟悉并且没有做过很多图形编程,但是我的游戏很小(只有十几个非常小的移动物体)所以我认为我可以天真地编程并仍然遇到没有性能问题。

毋庸置疑,我错了。游戏在大多数时间内表现不错,但是一旦有太多“敌人”在屏幕上移动或者分辨率过高,它开始变得明显变慢。

我已经确定了屏幕绘制功能的性能瓶颈,当这些功能被注释掉时,游戏速度非常快。

有人可以告诉我这里我可能做错了什么吗? (非常短的)源代码位于here,其中大部分是Main类,通常的嫌疑人是draw()中调用的inner game loop函数。 / p>

我已经使用BufferStrategy来更新屏幕,所以除非我做错了,否则这不应该是问题。

提前致谢, IDO。

4 个答案:

答案 0 :(得分:7)

一些观察,虽然我认为它们中的任何一个都没有多大帮助。

主要的是你正在绘制AWT线程。覆盖paintComponent(),而是在对象上调用repaint()。否则会导致各种各样的问题。

您可以每帧重新创建颜色。这可能是也可能不是您想要缓存的内容之一。我不认为虽然你的颜色有一个常数可能会搞砸GCing,并且当你想在以后重复使用颜色时会更容易保持直线。

每帧重绘整个窗口。您只需要重新绘制更改的部分。

您无需绘制背景。设置背景颜色,让父母照顾好一切。

作为一种设计,身体应该负责画画。他们的主人应该通知他们需要画画而不是画画。

身体每次都重建他们的状态。考虑让它们在不同时间存储并根据需要进行变异。您可能花了很多时间在drawCircleBody()

中进行trig计算

需要考虑的是设置计时器而不是在while循环中使用sleep。这将使您获得更加一致的帧速率,但是您需要确保您实际上能够履行您的义务(或者如果您错过最后期限,则将多个帧合并为一个)或者您最终会创建太多的线程。

考虑使用SwingWorker进行计算,然后在done()方法中更新状态,通过调用repaint()来完成。

这些只是一些事情。你应该试验看哪些有效,哪些无效。自从我完成Java图形绘制以来已经有一段时间了。

答案 1 :(得分:6)

您的代码未遵循单线程规则:

http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

我不确定这是否会导致你所看到的具体性能问题,但它是一个很大的潜在问题,imo。

答案 2 :(得分:6)

好吧,只是简单地看一下你的draw()函数,你似乎在宣告一些新对象(特别是在drawPolygonBody中)。尝试重复使用对象,而不是每次都声明一个新对象。

编辑:instanceof有开销。将Body扩展为具有绘制自身的绘制(Graphics g)函数将是一个更好的主意。例如:

public class Circle extends Body
{
    // override
    public void draw(Graphics g)
    {
        ...
    }
}

...

void drawBody(Body body) 
{
    body.draw();
}

答案 3 :(得分:4)

您是否尝试过分析它以查看绘图功能中哪里的瓶颈?

通过观察它很难说,但我想知道你为什么要在drawPolygonBody中绘制和填充多边形。
另外,在drawBoxBody中,你分别绘制了四行,而不是只调用drawRect()。