C语言SDL2游戏网格子数组意外消失问题求助
问题分析与修复方案
核心问题拆解
你的代码出现墙体突然消失、数组长度异常增长的问题,根源在于数组有效元素的维护逻辑错误,具体如下:
delete_grid_space移动元素的逻辑完全错误
当前循环从get_grid_length()开始遍历,但有效元素的索引范围是0到get_grid_length()-1,grid[get_grid_length()]属于未初始化的无效内存,把它赋值给前一位会引入垃圾数据,导致get_grid_length()统计出错误的元素数量。同时,删除元素后没有正确减少有效长度,只是把删除位置设为'\0'(即0.0f),如果游戏中存在Y=0的有效方块,会被误判为无效元素。move_grid_down的循环遍历逻辑错误
从前往后遍历数组并删除元素时,删除操作会导致后续元素左移,但循环索引i仍在递增,会跳过新移到当前位置的元素;同时依赖动态计算的get_grid_length()作为循环条件,会因为数组长度变化导致循环提前结束,部分元素未被处理。未维护明确的有效元素长度
依赖遍历数组判断元素是否有效(如是否为[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
相关产品推荐
相关产品推荐

