如何使用SDL_KeyCode实现每次按键仅触发一次处理逻辑
问题原因
- 你当前仅定义了
one、two两个固定的矩形变量,每次按下右方向键都会覆盖同一个one的坐标,没有存储历史生成的所有矩形 - 渲染逻辑仅固定绘制
one和two两个矩形,就算新增了矩形也不会被渲染 - 没有记录新矩形的生成位置偏移,每次生成的矩形坐标都是固定的(2,2),就算能生成多个也会重叠在一起
实现方案
你的思路是对的,确实需要用数组(动态数组最优)存储所有已生成的矩形,不用手动传递到事件处理逻辑,定义为全局变量或者封装到上下文里都可以。我们以C++实现为例,修改步骤如下:
- 引入动态数组容器,新增变量记录下一个矩形的x轴偏移
// 原有全局变量替换为以下内容 #include <vector> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *window = NULL; SDL_Surface *screen = NULL; SDL_Renderer *renderer; SDL_Event e; bool quit = false; // 存储所有生成的矩形 std::vector<SDL_Rect> rects; // 下一个生成的矩形x坐标,每次生成后偏移130保证不重叠 int next_rect_x = 2;
- 修改
logic函数的事件处理逻辑,按右键时新增矩形到容器,注意过滤长按重复触发的事件
void logic(){ while (SDL_PollEvent(&e) !=0) { if (e.type == SDL_KEYDOWN) { // 过滤长按重复触发的事件,仅第一次按下时生效 if(e.key.repeat == 0) { switch (e.key.keysym.sym) { case SDLK_RIGHT: // 新矩形加入容器 rects.push_back({next_rect_x, 2, 124, 124}); // 偏移x坐标,下次生成位置向右错开 next_rect_x += 130; break; case SDLK_LEFT: // 清空所有矩形,重置偏移 rects.clear(); next_rect_x = 2; break; } } } else if (e.type == SDL_QUIT) { quit = true; } } }
- 修改
draw函数,遍历容器绘制所有矩形
void draw(){ SDL_SetRenderDrawColor(renderer,255, 255, 255, 255); SDL_RenderClear(renderer); // 遍历所有矩形绘制 SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255); for(auto &rect : rects) { SDL_RenderFillRect( renderer, &rect); } SDL_RenderPresent(renderer); }
如果是纯C环境,把std::vector换成手动扩容的动态数组即可:定义一个SDL_Rect指针,一个记录当前数组长度的变量,一个记录数组容量的变量,每次新增元素时如果长度超过容量就用realloc扩容。
补充说明
如果需要不同矩形显示不同颜色,可以自定义结构体同时存储矩形坐标和颜色,再用动态数组存储该结构体即可:
// C语言可用的自定义结构体示例 typedef struct { SDL_Rect rect; SDL_Color color; } ColoredRect;
内容的提问来源于stack exchange,提问作者sellbyleth
相关产品推荐
相关产品推荐

