ncurses无法绘制预期正方形的技术问题求助
问题分析与修复方案
核心问题:值传递未修改全局对象
你的initSquare函数采用值传递,函数内部修改的是传入对象的副本,而非全局的ball对象。这导致ball的所有成员始终保持默认初始值0,Render中的判断条件永远不成立,最终屏幕全显示'0'。
修复步骤
1. 将initSquare改为引用传递
修改函数参数为引用类型,这样才能直接修改全局的ball对象:
// 修改函数声明 void initSquare(Square &square, float x, float y, int w, int h, char c); // 修改函数实现 void initSquare(Square &square, float x, float y, int w, int h, char c) { square.x = x; square.y = y; square.w = w; square.h = h; square.c = c; }
2. 修正Render的范围判断逻辑
原代码中j <= ball.x+ball.w会导致正方形多绘制一列,正确的范围应该是小于边界(宽度为w时,从x到x+w-1共w个字符):
if(j >= ball.x && j < ball.x + ball.w && i >= ball.y && i < ball.y + ball.h)
3. 增加退出逻辑与ncurses资源清理
原循环是死循环,无法正常退出,且未调用endwin()会导致终端状态异常。添加按键检测实现退出,并清理ncurses资源:
int main(void) { initscr(); cbreak(); // 让按键立即生效,无需等待回车 noecho(); // 不回显输入的字符 getmaxyx(stdscr, height, width); initSquare(ball, width/2, height/2, 4, 4, '#'); while(true) { Render(); usleep(35000); refresh(); // 按q键退出循环 if(getch() == 'q') { break; } } endwin(); // 清理ncurses资源,恢复终端正常状态 return 0; }
完整修复代码
#include <unistd.h> #include <ncurses.h> int height, width; class Square { public: float x; float y; int w; int h; char c; }; Square ball; void initSquare(Square &square, float x, float y, int w, int h, char c); void Render(); int main(void) { initscr(); cbreak(); noecho(); getmaxyx(stdscr, height, width); initSquare(ball, width/2, height/2, 4, 4, '#'); while(true) { Render(); usleep(35000); refresh(); if(getch() == 'q') { break; } } endwin(); return 0; } void initSquare(Square &square, float x, float y, int w, int h, char c) { square.x = x; square.y = y; square.w = w; square.h = h; square.c = c; } void Render() { for(int i = 0; i < height; ++ i) { for (int j = 0; j < width; ++ j) { if(j >= ball.x && j < ball.x + ball.w && i >= ball.y && i < ball.y + ball.h) { mvaddch(i, j, ball.c); } else { mvaddch(i, j, '0'); } } } }
内容的提问来源于stack exchange,提问作者Muffinz
相关产品推荐
相关产品推荐

