SDL按下1键时在鼠标坐标绘制‘1’纹理失败问题排查
问题:按下1键无法在鼠标位置绘制指定纹理
用户代码如下:
switch (e.type) { case SDL_QUIT: { quit = true; break; } case SDL_KEYDOWN: { switch (e.key.keysym.sym) { case SDLK_1: { SDL_Rect rect = {e.motion.x - 8, e.motion.y - 8, 16, 16}; SDL_RenderCopy(gRenderer, gT[3], NULL, &rect); printf("1\n"); break; } } break; } }
用户反馈按下1键后功能不生效,gT[3]是对应'1'的纹理,怀疑是按键判断相关问题,但不确定原因。
问题分析与解决步骤
核心问题1:KEYDOWN事件中无法通过
e.motion获取鼠标坐标
SDL的事件结构体是union类型,当事件类型为SDL_KEYDOWN时,只有e.key字段有效,e.motion属于鼠标移动事件的字段,此时访问会得到无效值。要获取当前鼠标坐标,应该用SDL_GetMouseState函数:int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); SDL_Rect rect = {mouseX - 8, mouseY - 8, 16, 16};核心问题2:缺少渲染刷新步骤
调用SDL_RenderCopy只是把纹理绘制到后台缓冲区,必须调用SDL_RenderPresent(gRenderer)才能把缓冲区内容显示到屏幕上,否则绘制的内容不会被用户看到。按键判断验证
代码里的SDLK_1是正确的按键常量,可通过printf("1\n")的输出情况判断按键事件是否触发:如果控制台能打印"1",说明按键判断没问题,问题出在坐标获取或渲染刷新;如果没打印,再检查事件循环是否正确调用SDL_PollEvent处理事件。
调整后的代码片段示例:
switch (e.type) { case SDL_QUIT: { quit = true; break; } case SDL_KEYDOWN: { switch (e.key.keysym.sym) { case SDLK_1: { int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); SDL_Rect rect = {mouseX - 8, mouseY - 8, 16, 16}; SDL_RenderCopy(gRenderer, gT[3], NULL, &rect); SDL_RenderPresent(gRenderer); // 新增渲染刷新步骤 printf("1\n"); break; } } break; } }
补充说明:如果你的渲染逻辑是在事件循环之外统一执行清屏、绘制、刷新操作,那可以不用在按键事件里单独调用SDL_RenderPresent,但要确保本次绘制操作在清屏之后、统一刷新之前执行。
内容的提问来源于stack exchange,提问作者yesyes
相关产品推荐
相关产品推荐

