正如标题所示,我正在寻找优化简单图块绘制算法的方法。我编写的代码使用了SFML以及我在不同章节中定义的几个类 - 但这些都不是必须知道我理解我的问题。
在我的代码中,我通过嵌套的for循环执行O(n ^ 3)操作。此代码的目的是逐层绘制位于矩形边界(命名为摄像机)内部的切片。
所以:
For Every Layer of tiles in a map:
For Every row of the Layer that is within camera bounds:
For Every Column element inside the camera bounds:
Retrieve the tile information from the map element at [layer,row,column]
Draw the the tiles texture to the screen, if it is a defined tile
这是我脑海中操作的基本概要。以下是我的实际代码:
camoffx = camera->GetTileOffset(tileSize).x;
camoffy = camera->GetTileOffset(tileSize).y;
for (int z = 0; z < curmap->GetDepth(); z++){
for (int y = 0, tileY = bounds.top; y < bounds.height; y++, tileY++){
for (int x = 0, tileX = bounds.left; x < bounds.width; x++, tileX++){
//Set our 'working' tile to null, incase we do not find a tile at specified z,x,y
tile = NULL;
//IF the tiles we are trying to view are out of the map bounds, do not draw them!
//this statement checks if the tiles we are trying to view are within our bounds.
if (tileX >= 0 && tileX < curmap->GetWidth() && tileY >= 0 && tileY < curmap->GetHeight()) tile = curmap->GetTile(z, tileX, tileY);
if (tile) tile->Draw((x * tileSize) - camoffx, (y * tileSize) - camoffy, window);
}
}
}
通过这种方式,您可以了解我的地图的存储方式 - 作为二维图块的图层。我可以从名为“Tiled Map Editor”的Tiled Map Editor创建的XML文件类型创建这些映射。解析器是我自己编写的,可以很好地完成工作。该算法的目的是将图块绘制到渲染屏幕。
到目前为止它的工作原理是足够的,但随着地图大小的增加,游戏引擎渲染屏幕的延迟也随之增加。作为一个小的压力测试我制作了5层x 100宽x100高32像素方块的地图。正如你猜测的那样,花了一些明显的时间来绘制5层位于相机边界的瓷砖(一个40瓦宽,30瓦高的矩形)。每帧绘制6,000个图块(最多)会影响性能。
我希望我可以从堆栈社区反弹(以及接收)优化的想法,希望通过上下文,你们可以拼凑出一些关于我的简单绘图系统如何工作的想法。
到目前为止的想法:
压缩地图: 5层将太多。将图块的纹理组合为两层。在玩家上方绘制的事物层,在玩家下方绘制的东西。
缩小相机尺寸: 40x30可能对我的个人项目来说有点雄心勃勃,直到我们发现摄像机界限的中位数足够大,可以玩游戏但小到足以达到最佳性能。
降低渲染率: 不是每帧渲染图块,而是每隔一帧或每隔三帧渲染一次(这样做会导致相机移动不稳定)。
您有什么想法/想法?我很乐意听到他们的声音!
答案 0 :(得分:0)
一个简单的优化是跳过完全在可见屏幕区域之外的任何图块。 SFML not cull绘制到屏幕外的位置。