昨天我刚刚完成了第14届Ludum Dare 48小时游戏制作大赛的my entry,并决定在java中使用java2d进行图形制作。
我对API不是很熟悉,也没有做过很多图形编程,但我的游戏非常小(只有十几个非常小的移动对象),所以我认为我可以很天真地对它进行编程,并且仍然没有遇到性能问题。
不用说,我错了。这款游戏大部分时间都表现良好,但一旦屏幕上有太多“敌人”在移动,或者分辨率调得太高,它就会开始变得明显变慢。
我已经确定了性能瓶颈是屏幕绘制函数,当这些函数被注释掉时,游戏的速度非常快。
有人能给我提个醒吗?我可能做错了什么?(非常简短的)源代码位于here,其中大部分是Main类,通常的疑点是在inner game loop中调用的draw()函数。
我已经使用了一个BufferStrategy来更新屏幕,所以这应该不是问题,除非我做错了。
提前谢谢你,伊多。
发布于 2009-04-20 16:15:23
一些观察,尽管我认为它们中的任何一个都不会有太大帮助。
最重要的是,您正在从AWT线程中绘制内容。重写paintComponent(),并在对象上调用repaint()。否则,这可能会导致各种问题。
您可以在每帧中重新创建颜色。这可能是也可能不是您想要缓存的内容之一。不过,我不认为为你的颜色设置一个常量可能会搞砸GCing,而且当你以后想要重用颜色时,会让事情变得更容易保持整洁。
每一帧都要重新绘制整个窗口。您只需要重新绘制更改过的部分。
你不需要画背景。设置背景颜色,让家长来处理所有的事情。
作为一个设计的东西,身体应该负责自己的绘图。它们的所有者应该通知它们需要绘制它们,而不是绘制它们。
这些身体每次都会重新创造出它们的状态。考虑让它们在两次之间存储它,并根据需要对它们进行修改。您可能会花费大量时间在drawCircleBody()中进行trig计算。
需要考虑的是设置一个计时器,而不是在while循环中使用睡眠。这将使您获得更一致的帧速率,但您需要确保您可以实际履行您的义务(或者,如果您错过了最后期限,则将多个帧合并为一个帧),否则您将创建太多线程。
考虑使用SwingWorker进行计算,然后在done()方法中更新状态,通过调用repaint()来完成。
这些只是几件事。你应该试着看看什么能用,什么不能用。我已经有一段时间没有做过Java图形绘制了。
发布于 2009-04-20 16:02:58
您的代码没有遵循单线程规则:
http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html
我不确定这是否会导致您所看到的特定性能问题,但它是一个很大的潜在问题,imo。
发布于 2009-04-20 16:03:13
看一下你的draw()函数,你似乎声明了一些新的对象(特别是在drawPolygonBody中)。尝试重用对象,而不是每次都声明一个新的对象。
编辑: instanceof有开销。更好的办法是扩展Body,使其具有一个可以绘制自身的绘图(Graphics g)函数。例如:
public class Circle extends Body
{
// override
public void draw(Graphics g)
{
...
}
}
...
void drawBody(Body body)
{
body.draw();
}
https://stackoverflow.com/questions/768871
复制相似问题