You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
            }
        }
    }
}

问题分析与解决思路

核心问题

  1. 换行符处理逻辑错误:当前代码遍历每行8个字符时,遇到\n仅跳过赋值但仍执行atIndex++,导致TXT中每行的换行符被计入遍历计数,把下一行的字符提前填充到当前行,破坏了网格的行列对应关系。比如TXT前7行每行是7个空格+1个0+换行(共9个字符),代码强制给每行塞8个字符,会把换行符后的下一行字符错误放入当前行。
  2. 行列与渲染坐标映射错位:代码用x作为行索引、y作为列索引,但渲染时直接使用(x*BLOCK_SIZE, y*BLOCK_SIZE),而OpenGL通常y轴向上,TXT从上到下的行对应渲染时从高到低的y坐标,直接映射会导致上下颠倒。
  3. 未初始化的垃圾值:遇到\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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:55:17