最近,我一直在尝试改进游戏中的一些延迟问题,而我正在做的一种方法是删除任何不必要的渲染。
这是render()
类中的TileMap
方法,用于处理游戏地图的创建,更新和渲染。
public void render(Graphics2D g) {
for(int row = 0; row < numRows; row++) {
for(int col = 0; col < numCols; col++) {
if(map[row][col] == 0) continue;
int rc = map[row][col];
int r = rc / numTilesAcross;
int c = rc % numTilesAcross;
g.drawImage(tiles[r][c].getImage(), x + (col * tileSize) - 8, y + (row * tileSize) - 8, null);
}
}
}
我一直在尝试这样的事情:
if(x + (col * tileSize) - 8 < x + (col * tileSize) - 8 + Panel.WIDTH) continue;
Panel.WIDTH
是窗口的宽度。我不确定需要哪些算法来测试越界渲染。
检查瓷砖是否在屏幕左侧,但这不起作用。
我还认为循环遍历所有的行和列可能是滞后的,我想要更改它,以便它只循环通过可以在屏幕上呈现的图块数量。
答案 0 :(得分:1)
创建一些临时变量将有助于使其更容易理解:
int pixelX = x + (col * tileSize) - 8;
int pixelY = y + (row * tileSize) - 8;
使用这些,您建议的检查等同于:
if(pixelX < pixelX + Panel.WIDTH) continue;
显然不会跳过任何东西。
你想要这样的东西:
if(pixelX + tilesize <= 0) continue; // tile is off left side of screen
if(pixelY + tilesize <= 0) continue; // tile is off top of screen
if(pixelX >= Panel.WIDTH) continue; // tile is off right side of screen
if(pixelY >= Panel.HEIGHT) continue; // tile is off bottom of screen
假设Panel.WIDTH
和Panel.HEIGHT
是您正在绘制的东西的宽度和高度。这是轴对齐边界框的碰撞检查,以防您需要搜索名称。
这仍然不是最有效的方式 - 您最终会在整个地图上循环,但随后会忽略大部分图块。一种更有效的方法是计算您可以看到的地图部分,然后绘制这些图块:
// assuming x <= 8 and y <= 8
int firstCol = ((8-x) / tileSize);
int firstRow = ((8-y) / tileSize);
int lastCol = firstCol + ((Panel.WIDTH + tileSize - 1) / tileSize); // Panel.WIDTH/tileSize, but rounding up
int lastRow = firstRow + ((Panel.HEIGHT + tileSize - 1) / tileSize);
for(int row = lastRow; row <= firstRow; row++) {
for(int col = lastCol; col <= firstCol; col++) {
// drawing code goes here
// there's no need to test the tile is onscreen inside the loop
}
}