我刚刚参加了第14届Ludum Dare 48小时游戏制作比赛my entry,并决定在java中使用java2d进行图形处理。
我对API并不熟悉并且没有做过很多图形编程,但是我的游戏很小(只有十几个非常小的移动物体)所以我认为我可以天真地编程并仍然遇到没有性能问题。
毋庸置疑,我错了。游戏在大多数时间内表现不错,但是一旦有太多“敌人”在屏幕上移动或者分辨率过高,它开始变得明显变慢。
我已经确定了屏幕绘制功能的性能瓶颈,当这些功能被注释掉时,游戏速度非常快。
有人可以告诉我这里我可能做错了什么吗? (非常短的)源代码位于here,其中大部分是Main类,通常的嫌疑人是draw()中调用的inner game loop函数。 / p>
我已经使用BufferStrategy来更新屏幕,所以除非我做错了,否则这不应该是问题。
提前致谢, IDO。
答案 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()。