如何加快我的游戏速度?

时间:2011-12-20 21:27:57

标签: java performance

我有我的游戏,在每个渲染循环中,循环遍历我的地图中的所有块(128x128),这可能会导致很多延迟。当我第一次制作它时,我不得不让它只渲染屏幕上的块,否则它会立即崩溃。现在我只在屏幕上渲染块,但仍然遍历所有块以查看它们是否在屏幕上,这使得我的fps大约为2。

    for (int y = 0; y < 128; y++) {
        for (int x = 0; x < 128; x++) {
            Block b = LevelGen.getBlockAt(x, y);
            if (Forgotten.isInsideGameWindow(x * 30, y * 30)) {
                arg1.drawImage(b.getTexture(), x * 30, y * 30);
            }
        }
    }

有没有办法让它不会遍历所有这些?

3 个答案:

答案 0 :(得分:3)

计算显示窗口的大小,并仅迭代其中的块。

final int tile_size = 30;

final RectangleType displayWindow = Forgotten.getDisplayWindow ();

final int left = displayWindow.getLeft () / tile_size - 1;
final int right = displayWindow.getRight () / tile_size + 1;
final int top = displayWindow.getTop () / tile_size - 1;
final int bottom = displayWindow.getBottom () / tile_size + 1;

for (int y = top; y < bottom; ++y)
   for (int x = left; x < right; ++x)
       canvas.drawImage (LevelGen.getBlockAt (x,y).getTexture (),
                         x * tile_size, y * tile_size);

您可能还想弄清楚画布的哪个区域实际上是想要绘制的,而是保留一个“脏矩形”列表来重绘区域。每当瓷砖更改,或精灵/粒子/通过其空间的任何内容时,将该瓷砖添加到矩形。即使您只是使用一个放大的单个脏矩形来包含一帧中的所有更新,如果您的游戏实际上并未在显示屏上的所有点上实际发生“发生”,那么您的帧速率将会更高(但遭受大规模影响)

扩展:

      public class Map {
            private Rectangle dirtyRect = null;

            public void dirty (Rectangle areaAffected) {
                   if (null == dirtyRect) {
                        dirtyRect = areaAffected; return;
                   }
                   dirtyRect = new Rectangle ( Math.min (dirtyRect.getLeft (),
                                                         areaAffected.getLeft () ),
                                               Math.min (dirtyRect.getTop (),
                                                         areaAffected.getTop () ),
                                               Math.max (dirtyRect.getRight (),
                                                         areaAffected.getRight () ),
                                               Math.max (dirtyRect.getBottom (),
                                                         areaAffected.getBottom () ));
            }

然后使用脏矩形代替displayWindow进行常规绘制,如果没有任何更改,您可以测试if (null == getDirtyRectangle ()) return;以完全跳过绘图。

答案 1 :(得分:0)

您可以在代码块中插入一个中断..但是我没有看到此代码的目的是查看16,32或256次......

答案 2 :(得分:0)

好吧,您可以将所有块放在一个数组中,在块对象中包含坐标,然后使用它们来绘制块。然后你只需要遍历屏幕上显示的块。仅在屏幕上没有那么多块时才有用。