使用SDL2的SDL_RenderFillRect渲染矩形失败窗口全黑如何解决?
问题原因
- 未处理SDL事件队列:SDL要求必须定期排空事件队列,否则操作系统会判定程序未响应,所有渲染操作都不会更新到窗口上,这是你窗口一直显示黑色的核心原因。
- 渲染矩形的透明度设置错误:你在绘制矩形时给
SDL_SetRenderDrawColor传的alpha值是0,代表完全透明,就算绘制逻辑正确也看不到矩形。
- 渲染矩形的透明度设置错误:你在绘制矩形时给
- 帧率延迟逻辑语法错误:
SDL_Delay(timerFPS<((1000/60)-timerFPS))行中,你把判断条件直接当成了延迟参数,表达式结果只有0或1,完全起不到控制帧率的作用。
- 帧率延迟逻辑语法错误:
- 球的坐标未初始化:
initRects中只设置了Ball的宽高,x/y坐标为未初始化的垃圾值,大概率在窗口可视区域外。
- 球的坐标未初始化:
- 主循环逻辑错误:你在第一次循环结束就直接设置
running=0退出程序,没有给窗口渲染和事件响应留足够的运行时间。
- 主循环逻辑错误:你在第一次循环结束就直接设置
修正方案
1. 修正run函数,添加事件处理
void Game::run() { initRects(); SDL_Event e; while(running) { // 处理事件队列 while(SDL_PollEvent(&e)) { if(e.type == SDL_QUIT) { running = 0; } } lastFrame=SDL_GetTicks(); if(lastFrame>=(lastTime+1000)) { lastTime=lastFrame; fps=frameCount; frameCount=0; } render(); } }
2. 修正render函数的透明度和延迟逻辑
void Game::render() { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); frameCount++; timerFPS=SDL_GetTicks()-lastFrame; // 修正帧率控制逻辑 if(timerFPS < (1000/60)) { SDL_Delay(1000/60 - timerFPS); } // 修正alpha值为255(完全不透明) SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 255); SDL_RenderFillRect(renderer, &lPaddle); SDL_RenderFillRect(renderer, &rPaddle); SDL_RenderFillRect(renderer, &Ball); SDL_RenderPresent(renderer); }
3. 补充Ball的坐标初始化
void Game::initRects() { lPaddle.x=32; lPaddle.h=HEIGHT/5; lPaddle.y=(HEIGHT/2)-(lPaddle.h/2); lPaddle.w=12; rPaddle=lPaddle; rPaddle.x=WIDTH-rPaddle.w-32; Ball.w=Ball.h=16; // 新增:球初始放在屏幕中心 Ball.x = WIDTH/2 - Ball.w/2; Ball.y = HEIGHT/2 - Ball.h/2; }
修正后运行即可看到左右两个挡板和中心的白球。
内容的提问来源于stack exchange,提问作者Leon4sennato
相关产品推荐
相关产品推荐

