Mac环境C++ SDL2开发 SDL_PointInRect判断语句不生效问题
问题根因与修复方案
你代码的if判断失效是网格数组初始化不完整、数组越界访问共同导致的未定义行为,你取反条件后看似正常运行,只是垃圾值触发的巧合结果。具体问题和修复方法如下:
核心问题梳理
- 网格数组赋值逻辑错误
你在RenderRects的双层循环中,仅使用grid[i].Rect = Rect赋值,内层循环的y坐标变量j完全没有参与数组索引计算,同一x坐标下不同y位置的矩形会反复覆盖同一个数组元素的Rect属性。最终只有144个(1440/10)数组元素的Rect是有效值,剩余22万+元素的Rect都是未初始化的垃圾值,自然无法命中鼠标点击判断。 - 数组越界访问
你定义的grid数组长度为228960,合法索引范围是0~228959,但ToggleRect中的循环判断条件为i < 228961,会访问超出数组边界的内存,属于标准未定义行为。 - 冗余数组定义与无意义遍历
你当前的10px大小网格,x方向最多144个、y方向最多80个,总共仅需11520个数组元素即可,定义22万长度的数组完全冗余;遍历全部数组判断点击的逻辑也远不如直接计算索引高效。
修复代码示例
首先定义全局常量避免魔法值,修改数组长度:
#include <iostream> #include <SDL2/SDL.h> const int GRID_SIZE = 10; const int GRID_COLS = 1440 / GRID_SIZE; const int GRID_ROWS = 800 / GRID_SIZE; void RenderRects(SDL_Renderer *renderer); void ToggleRect(int MouseX, int MouseY); struct Grid { bool IsActive; SDL_Rect Rect; }; // 数组长度调整为实际需要的大小 Grid grid[GRID_COLS * GRID_ROWS];
修改RenderRects的索引计算逻辑:
void RenderRects(SDL_Renderer *renderer) { for (int x = 0; x < 1440; x += GRID_SIZE) { for (int y = 0; y < 800; y += GRID_SIZE) { int col = x / GRID_SIZE; int row = y / GRID_SIZE; int index = col * GRID_ROWS + row; grid[index].Rect = {x, y, GRID_SIZE, GRID_SIZE}; SDL_SetRenderDrawColor(renderer, 100, 100, 100, 225); SDL_RenderDrawRect(renderer, &grid[index].Rect); // 如果要渲染激活状态可以在这里加判断改颜色 } } }
修改ToggleRect的点击判断逻辑,无需遍历全数组:
void ToggleRect(int MouseX, int MouseY) { int col = MouseX / GRID_SIZE; int row = MouseY / GRID_SIZE; // 先判断坐标是否在网格范围内 if (col >= 0 && col < GRID_COLS && row >=0 && row < GRID_ROWS) { int index = col * GRID_ROWS + row; std::cout << index << std::endl; // 切换激活状态逻辑 grid[index].IsActive = !grid[index].IsActive; } }
内容的提问来源于stack exchange,提问作者DischordDynne
相关产品推荐
相关产品推荐

