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

C语言SDL2游戏网格子数组意外消失问题求助

问题分析与修复方案

核心问题拆解

你的代码出现墙体突然消失、数组长度异常增长的问题,根源在于数组有效元素的维护逻辑错误,具体如下:

  1. delete_grid_space移动元素的逻辑完全错误
    当前循环从get_grid_length()开始遍历,但有效元素的索引范围是0到get_grid_length()-1,grid[get_grid_length()]属于未初始化的无效内存,把它赋值给前一位会引入垃圾数据,导致get_grid_length()统计出错误的元素数量。同时,删除元素后没有正确减少有效长度,只是把删除位置设为'\0'(即0.0f),如果游戏中存在Y=0的有效方块,会被误判为无效元素。

  2. move_grid_down的循环遍历逻辑错误
    从前往后遍历数组并删除元素时,删除操作会导致后续元素左移,但循环索引i仍在递增,会跳过新移到当前位置的元素;同时依赖动态计算的get_grid_length()作为循环条件,会因为数组长度变化导致循环提前结束,部分元素未被处理。

  3. 未维护明确的有效元素长度
    依赖遍历数组判断元素是否有效(如是否为[0,0])来获取长度,这种方式容易出现误判,且无法实时跟踪数组的真实有效状态,最终导致长度异常增长到64后触发未知错误,重置为初始长度8。


修复后的代码实现

1. 新增全局变量跟踪有效长度

#include <SDL2/SDL.h>

#define GRID_MAX_ITEMS 255
#define GRID_SPACE_SIZE 30
#define FRAME_TARGET_TIME 16 // 假设60帧,每帧16ms

float grid[GRID_MAX_ITEMS][2];
int grid_length = 0; // 明确跟踪当前有效元素的数量
int GRID_ROWS = 0; // 记录下一行要生成的Y坐标

2. 修正delete_grid_space函数

void delete_grid_space(int index) {
    // 过滤非法索引
    if (index < 0 || index >= grid_length) return;

    // 将index之后的所有有效元素左移一位
    for (int i = index; i < grid_length - 1; i++) {
        grid[i][0] = grid[i+1][0];
        grid[i][1] = grid[i+1][1];
    }

    // 标记最后一个原有效位置为无效(可选,避免垃圾数据干扰)
    grid[grid_length - 1][0] = -9999.0f;
    grid[grid_length - 1][1] = -9999.0f;

    // 有效长度减1
    grid_length--;
}

3. 修正move_grid_down函数

void move_grid_down(float change) {
    // 从后往前遍历,避免删除元素导致的索引混乱
    for (int i = grid_length - 1; i >= 0; i--) {
        grid[i][1] -= change;
        // 元素移出屏幕,删除
        if (grid[i][1] < -GRID_SPACE_SIZE) {
            delete_grid_space(i);
        }
    }

    // 判断是否需要生成新行:要么数组为空,要么最后一行与下一行间隔≥6
    if (grid_length == 0 || (GRID_ROWS - grid[grid_length - 1][1]) >= 6) {
        add_row(GRID_ROWS);
        GRID_ROWS += 6; // 确保下一行间隔6个单位
    }
}

4. 简化get_grid_length函数

int get_grid_length() {
    return grid_length;
}

5. 初始化grid的逻辑调整

在init_grid中,生成初始墙体后,记得设置grid_length为初始有效元素数量,例如:

void init_grid() {
    // 示例:生成初始的8个元素
    grid[0][0] = 0; grid[0][1] = 5;
    grid[1][0] = 1; grid[1][1] = 5;
    grid[2][0] = 2; grid[2][1] = 5;
    grid[3][0] = 3; grid[3][1] = 5;
    grid[4][0] = 6; grid[4][1] = 5;
    grid[5][0] = 7; grid[5][1] = 5;
    grid[6][0] = 8; grid[6][1] = 5;
    grid[7][0] = 9; grid[7][1] = 5;
    grid_length = 8;
    GRID_ROWS = 5 + 6; // 下一行Y坐标为11
}

额外注意事项

  • 原代码中add_row(GRID_ROWS + 1)的逻辑可能有误,修复后改为add_row(GRID_ROWS)并递增GRID_ROWS,确保新行与最后一行间隔严格为6个单位。
  • 避免用'\0'给float类型赋值,改用不可能出现的极端值(如-9999.0f)标记无效元素,防止误判有效方块。
  • 确保add_row函数在添加新元素时,先检查grid_length < GRID_MAX_ITEMS,避免数组越界。

内容的提问来源于stack exchange,提问作者Charlie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:08:13