如何在C语言的Ncurses中实现独立于用户输入的自主移动
问题
我希望让字符“o”独立于用户输入向下移动,计划将用户输入用于控制另一个对象。在没有输入判断时,“o”会正常向下移动;但加入getch()后,只有存在用户输入时“o”才会移动。
以下是我的测试代码:
while(1) { clear(); // Clear the screen of all previously-printed characters mvprintw(y, x, "o"); // Print our "ball" at the current xy position int ch = getch(); //THE PROBLEM // Move the player's ship left or right based on user input, currently controls the "o" IKNOW. IT's JUST TESTING. THAT"S BESIDES THE PROBLEM if (ch == 'a') x--; else if(ch == 'd') x++; else if(ch == 'q') break;// quit option refresh(); usleep(DELAY); // Shorter delay between movements y++; // Advance the ball down }
我尝试过使用不同循环、将移动逻辑放到单独函数中,但仍需要将移动逻辑保留在while循环内。我得知while(1)是用于每帧更新,但当前程序必须等待用户输入才会进入下一帧。请问该如何实现“o”的独立移动?
解决方法
问题出在getch()默认是阻塞调用——它会一直等着用户输入,不输入就不往下执行,自然“o”没法自动移动。要让程序不管有没有输入都能继续跑,得把输入改成非阻塞模式:
- 在ncurses初始化(比如
initscr())之后,加一句nodelay(stdscr, TRUE);,这样getch()会立刻返回,没输入时返回ERR。 - 修改输入处理逻辑,只有当
getch()返回的不是ERR时,才处理用户输入,否则直接跳过输入判断,继续执行移动和刷新。
修改后的代码示例:
// 初始化ncurses后添加这句 nodelay(stdscr, TRUE); while(1) { clear(); mvprintw(y, x, "o"); int ch = getch(); // 只有获取到有效输入时才处理 if (ch != ERR) { if (ch == 'a') x--; else if(ch == 'd') x++; else if(ch == 'q') break; } refresh(); usleep(DELAY); y++; // 不管有没有输入,球都会向下移动 }
也可以用timeout(0);代替nodelay(),效果完全一样——它把getch()的超时时间设为0毫秒,同样会立即返回。
注意:开启非阻塞后循环会跑得更快,要调整DELAY的值,避免“o”移动速度超出预期。
内容的提问来源于stack exchange,提问作者Mangoes
相关产品推荐
相关产品推荐

