4

我昨天刚刚完成了第 14 届 Ludum Dare 48 小时游戏制作比赛的参赛作品 ,并决定在 java 中使用 java2d 进行图形制作。

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

不用说,我错了。游戏在大多数情况下都运行良好,但一旦屏幕上移动的“敌人”太多或分辨率太高,它就会开始明显变慢。

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

有人可以告诉我我在这里可能做错了什么吗?(非常短的)源代码位于此处,其中大部分是Main类,通常怀疑是在内部游戏循环中调用的draw()函数。

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

在此先感谢,伊多。

4

4 回答 4

7

一些观察,尽管我认为它们中的任何一个都不会有太大帮助。

主要的是您正在绘制 AWT 线程。覆盖 paintComponent() 并改为在对象上调用 repaint()。否则,这可能会导致各种问题。

您每帧都重新创建颜色。这可能是也可能不是您要缓存的内容之一。我不认为为你的颜色设置一个常量可能会搞砸 GCing,并且当你以后想要重用颜色时会让事情变得更容易。

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

你不需要画背景。设置背景颜色,让父母处理一切。

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

身体每次都重新创建它们的状态。考虑让他们在不同时间之间存储它并根据需要对其进行变异。您可能会花费大量时间在 drawCircleBody() 中进行三角计算

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

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

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

于 2009-04-20T16:15:23.010 回答
6

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

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

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

于 2009-04-20T16:02:57.563 回答
6

好吧,简单地看一下您的 draw() 函数,您似乎正在声明许多新对象(尤其是在 drawPolygonBody 中)。尝试重用对象,而不是每次都声明一个新对象。

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

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

...

void drawBody(Body body) 
{
    body.draw();
}
于 2009-04-20T16:03:12.633 回答
4

您是否尝试过对其进行分析以查看绘图功能中的瓶颈在哪里

光看它很难说太多,但我想知道为什么你在 drawPolygonBody 中绘制和填充多边形。
此外,在 drawBoxBody 中,您分别绘制四条线,而不仅仅是调用 drawRect()。

于 2009-04-20T16:04:52.113 回答