我正在使用 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/