简体   繁体   English

检查是否在屏幕外渲染?

[英]Check if Rendering Off Screen?

Recently, I've been trying to improve some lag issues in my game, and one way I'm doing that is my removing any unnecessary rendering. 最近,我一直在尝试改善游戏中的一些滞后问题,而这样做的一种方法是删除所有不必要的渲染。

This is the render() method in my TileMap class, which handles creating, updating, and rendering game maps. 这是我的TileMap类中的render()方法,用于处理游戏地图的创建,更新和渲染。

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);

        }

    }

}

I've been trying things like this: 我一直在尝试这样的事情:

if(x + (col * tileSize) - 8 < x + (col * tileSize) - 8 + Panel.WIDTH) continue;

With Panel.WIDTH being the width of the window. 使用Panel.WIDTH为窗口的宽度。 I'm not really sure what algorithms are needed to test for out of bounds rendering. 我不太确定需要什么算法来测试越界渲染。

To check if the tiles were off the left of the screen, but that didn't work. 要检查磁贴是否在屏幕左侧,但是没有用。

I also think looping through all the rows and columns might be laggy, and I want to change it so it only loops though the amount of tiles that can be rendered on the screen. 我还认为循环遍历所有行和列可能会比较费时,因此我想对其进行更改,以使其仅循环遍历可在屏幕上呈现的瓦片数量。

Creating some temporary variables would help make that more understandable: 创建一些临时变量将有助于使它更易于理解:

int pixelX = x + (col * tileSize) - 8;
int pixelY = y + (row * tileSize) - 8;

Using these, the check you suggested is equivalent to this: 使用这些,您建议的检查与此等效:

if(pixelX < pixelX + Panel.WIDTH) continue;

which obviously isn't going to skip anything. 显然不会跳过任何内容。

You want something like this: 您想要这样的东西:

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

Assuming Panel.WIDTH and Panel.HEIGHT are the width and height of the thing you're drawing on. 假设Panel.WIDTHPanel.HEIGHT是要绘制的东西的宽度和高度。 This is a collision check for axis-aligned bounding boxes, in case you need a name to search for. 如果需要搜索名称,这是对轴对齐的边界框的碰撞检查。

This is still not the most efficient way - you end up looping over the entire map, but then ignore most of the tiles. 这仍然不是最有效的方法-您最终会遍历整个地图,但随后忽略了大多数图块。 A more efficient way is to calculate the part of the map that you can see, and then draw those tiles: 一种更有效的方法是计算您可以看到的地图部分,然后绘制这些图块:

// 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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM