c++ - 如何迭代 vector C++ 中的特定元素?

标签 c++ optimization iteration sfml game-development

我正在使用 C++ 和 SFML 制作游戏,想知道是否有一种方法可以迭代 vector 中的特定元素。我有一个组成游戏世界的图 block vector ,但根据游戏 map 的大小(1000 x 1000 个图 block )迭代所有这些图 block 似乎效率非常低。我想知道是否有一种方法可以说“对于瓷砖 vector 中的每个瓷砖(适合条件)”。现在,我绘制这些图 block 的代码如下所示:

void Tile::draw()
{
    for (const auto& TILE : tiles)
    {
        if (TILE.sprite.getGlobalBounds().intersects(Game::drawCuller.getGlobalBounds()))
        {
            Game::window.draw(TILE.sprite);
        }
    }
}

如您所见,我只是在 View (或drawculler)中绘制图 block 。如果 vector 太大,则迭代它需要很长时间。这极大地影响了我的 fps。当我有 100 x 100 瓦片 map 时,我得到大约 800 fps,但是当我使用 1000 x 1000 瓦片 map 时,由于迭代时间长,我得到大约 25 fps。我知道我可以将我的图 block 分成 block ,并且只迭代当前 block 中的 block ,但我想要一些更容易实现的东西。任何帮助将不胜感激:)

最佳答案

考虑到以下假设:

  • 您的图 block 可能排列在带有(列、行)索引的规则网格上。
  • 您的图 block 可能会按行主顺序插入到 vector 中,并且也可能已完全填充。因此 vector 中图 block 的索引可能是 (row * numColumns + column) .
  • 您的 View 可能与网格轴对齐(您无法旋转 View - 正如许多基于图 block 的 2D 游戏的情况)

如果这些假设成立,那么您可以使用嵌套循环轻松迭代适当范围的图 block 。

for (int row = minRow; row <= maxRow; ++row) {
   for( int column = numColumn; column <= maxColumn; ++column) {
      int index = row * numColumns + column;

      // Here you can...
      doSomethingWith(tiles[index]);
   }
}

这只需要您可以计算 minRow , maxRow , minColumn ,和maxColumn来自您的Game::drawCuller.getGlobalBounds() 。您尚未透露详细信息,但它可能类似于世界坐标中的矩形(可能采用某些单位,如米)。它可能是 left , top , width , height样式矩形或 min , max样式边界矩形。假设后者:

minViewColumn = floor((bounds.minInMeters.x - originOfGridInMeters.x) / gridTileSizeInMeters);
maxViewColumn = ceil((bounds.maxInMeters.x - originOfGridInMeters.x) / gridTileSizeInMeters);
// similarly for rows
minViewRow = floor((bounds.minInMeters.y - originOfGridInMeters.y) / gridTileSizeInMeters);
maxViewRow = ceil((bounds.maxInMeters.y - originOfGridInMeters.y) / gridTileSizeInMeters);

originOfGridInMeters是图 block 左上角的全局坐标(行 = 0,列 = 0),如果您这样设置世界,很可能是 (0, 0)。和gridTileSizeInMeters嗯,就是这样;想必您的图 block 在世界空间中具有正方形的纵横比。

如果允许 View 超出图 block 数组的范围,minViewColumn ,(以及其他迭代器范围)现在可能小于 0 或大于或等于平铺数组中的列数。因此,需要计算 minColumn来自minViewColumn通过剪切它到存储在网格中的图 block 范围。 (其他迭代范围也是如此。)

// Clip to the range of valid rows and columns.
minColumn = min(max(minViewColumn, 0), numColumns - 1);
maxColumn = min(max(maxViewColumn, 0), numColumns - 1);
minRow = min(max(minViewRow, 0), numRows - 1);
maxRow = min(max(maxViewRow, 0), numRows - 1);

现在执行我上面向您展示的循环,就可以开始了!

关于c++ - 如何迭代 vector C++ 中的特定元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72568783/

相关文章:

java - 在迭代期间更改 HashMap 键

c++ - Visual Studio 2017 的 CMake 多项目设置

c++ - 获取C++中最大的有符号整数类型

c++ - VS 是否优化了相同类型的转换?

xml - 如何让 Powershell 更快地解析 XML 或进一步优化我的脚本?

algorithm - 优化的 TSP 算法

c++ - qVariantValue 是 "QT_DEPRECATED"- 替换的是什么?

c++ - 生成一个数的所有因数分解

for-loop - 替代 Julia 中的嵌套 for 循环

对象列表的 Python 迭代 "not iterable"