我有我的游戏,在每个渲染循环中,它循环遍历地图中的所有块(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);
}
}
}
有没有办法使它们不会遍历所有对象?
最佳答案
找出显示窗口的大小,然后仅迭代其中的块。
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;
完全跳过绘制。