C++中字符串网格关卡转二维数组异常,求排查解决
问题求助:字符串网格转二维数组渲染异常
近一两天一直被这个问题卡着,麻烦大家帮忙看看。我要把TXT里的字符串网格关卡转成数字二维数组,但转换后渲染效果不对。已经确认两点:
- 已正确读取TXT文件
- 手动设置数值时,OpenGL能正常渲染对象
关卡TXT内容
0 0 0 0 0 0 0 00000000
异常情况说明
实际渲染结果和预期不符,预期是和TXT里的0位置对齐,但当前输出错位(实际输出为渲染错位的网格,0的位置与TXT中完全不对应)
转换代码(xSize和ySize均为8)
levelDat = new char* [xSize]; int atIndex = 0; for (int x = 0; x < xSize; x++) { levelDat[x] = new char[ySize]; for (int y = 0; y < ySize; y++) { if (level[atIndex] != '\n') { levelDat[x][y] = level[atIndex]; } atIndex++; } } for (int x = 0; x < xSize; x++) { for (int y = 0; y < ySize; y++) { if (levelDat[x][y] != AIR) { blockDat.push_back(x * BLOCK_SIZE); blockDat.push_back(y * BLOCK_SIZE); switch (levelDat[x][y]) { case DIRT: blockDat.push_back(1); break; default: blockDat.push_back(0); break; } } } }
问题分析与解决思路
核心问题
- 换行符处理逻辑错误:当前代码遍历每行8个字符时,遇到
\n仅跳过赋值但仍执行atIndex++,导致TXT中每行的换行符被计入遍历计数,把下一行的字符提前填充到当前行,破坏了网格的行列对应关系。比如TXT前7行每行是7个空格+1个0+换行(共9个字符),代码强制给每行塞8个字符,会把换行符后的下一行字符错误放入当前行。 - 行列与渲染坐标映射错位:代码用
x作为行索引、y作为列索引,但渲染时直接使用(x*BLOCK_SIZE, y*BLOCK_SIZE),而OpenGL通常y轴向上,TXT从上到下的行对应渲染时从高到低的y坐标,直接映射会导致上下颠倒。 - 未初始化的垃圾值:遇到
\n时levelDat[x][y]未赋值,残留的垃圾值可能干扰后续的AIR判断。
修正方案
1. 正确按行分割并填充数组
先把读取到的字符串按换行分割成每行,再将每行补空格至8个字符,确保每行正好对应二维数组的一行:
// 按换行分割每行字符串 vector<string> lines; stringstream ss(level); string line; while (getline(ss, line)) { // 补空格到8个字符,不足补空格,过长截断 if (line.length() < ySize) { line.append(ySize - line.length(), ' '); } else if (line.length() > ySize) { line = line.substr(0, ySize); } lines.push_back(line); } // 初始化二维数组并填充 levelDat = new char*[xSize]; for (int x = 0; x < xSize; x++) { levelDat[x] = new char[ySize]; // 先全部初始化为AIR,避免垃圾值 memset(levelDat[x], AIR, ySize); if (x < lines.size()) { for (int y = 0; y < ySize; y++) { levelDat[x][y] = lines[x][y]; } } }
2. 修正渲染坐标映射
将TXT的行索引转换为OpenGL的垂直坐标(TXT第一行对应渲染顶部):
for (int x = 0; x < xSize; x++) { for (int y = 0; y < ySize; y++) { if (levelDat[x][y] != AIR) { // 转换行索引为垂直方向的渲染坐标(从上到下对应y从高到低) int renderY = (xSize - 1 - x) * BLOCK_SIZE; // y对应水平方向,x转换后对应垂直方向 blockDat.push_back(y * BLOCK_SIZE); blockDat.push_back(renderY); switch (levelDat[x][y]) { case DIRT: blockDat.push_back(1); break; default: blockDat.push_back(0); break; } } } }
内容的提问来源于stack exchange,提问作者kresty1
相关产品推荐
相关产品推荐

