SFML绘制2D游戏瓦片地图触发Vector Subscript out of range错误
问题分析与修复方案
1. 瓦片初始化未执行且不完整
GameMap构造函数仅调用了setUpInitialState(),未触发setUpTiles(),导致tiles向量完全未初始化;同时原setUpTiles()只生成了1行瓦片,而网格长度设为8,后续访问非0行必然越界。
修复:
- 在构造函数中补全初始化调用:
GameMap::GameMap() { gridLength = 8; setUpInitialState(); setUpTiles(); setUpEnemyPosition(); }
- 重写
setUpTiles()生成完整的8x8瓦片网格:
void GameMap::setUpTiles() { tiles.clear(); const std::string tilePath = "Pixel Crawler - Free Pack/Environment/Tilesets/Floors_Tiles.png"; for (int row = 0; row < gridLength; ++row) { std::vector<GameTile*> currentRow; for (int col = 0; col < gridLength; ++col) { float x = col * 50.0f; float y = row * 50.0f; GameTile* tile = new GameTile(tilePath, x, y, true, false); tile->setUpSprite(tilePath); currentRow.push_back(tile); } tiles.push_back(currentRow); } }
2. GameTile构造函数参数错误
构造函数第一个std::string参数未声明变量名,无法接收纹理路径;且未调用setUpSprite(),瓦片纹理根本未加载。
修复:
修正构造函数并补全纹理加载调用:
GameTile::GameTile(std::string textureName, float x, float y, bool goThrough, bool exit) : sprite(texture) { position = sf::Vector2f(x, y); sprite.setPosition(position); CanMoveThrough = goThrough; isExit = exit; setUpSprite(textureName); }
3. 渲染循环索引越界
main中的嵌套循环存在两处致命错误:
- 外层循环
i从gridLength(值为8)开始,而瓦片合法索引为0~7,直接越界; - 内层循环
j的条件为j >= gridLength,仅会执行j=8,但tiles仅8行(索引0~7),完全超出范围。
修复:
调整循环遍历所有合法瓦片索引:
// 正向渲染所有瓦片 for (int row = 0; row < WorldMap.gridLength; ++row) { for (int col = 0; col < WorldMap.gridLength; ++col) { window->draw(WorldMap.tiles[row][col]->sprite); } }
若需要从下往上渲染,可改为:
for (int row = WorldMap.gridLength - 1; row >= 0; --row) { for (int col = 0; col < WorldMap.gridLength; ++col) { window->draw(WorldMap.tiles[row][col]->sprite); } }
4. 内存泄漏修复(额外提示)
使用new创建的GameTile对象未被释放,会导致内存泄漏,需在GameMap析构函数中清理:
GameMap::~GameMap() { for (auto& row : tiles) { for (auto tile : row) { delete tile; } } }
内容的提问来源于stack exchange,提问作者Nobody2x0x
相关产品推荐
相关产品推荐

