我正在使用ncurses进行打字游戏.字母从屏幕上掉下来,您必须在它们到达底部之前键入它们.除了一个问题外,它工作得很好.清除窗口(使用clear())会使输出闪烁.我在循环的开头放了clear(),在最后放了wrefresh().它不应该等待直到wrefresh显示任何东西,因此不闪烁?
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <curses.h>
#include <fstream>
using namespace std;
int main(){
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
srand(time(NULL));
//input character integer (ASCII)
int ch = 1;
//int to store the last time the character positions were updated
int lastupdate = time(NULL);
//x,y,char arrays for falling characters and initialization
int chars[10], x[10], y[10];
for(int i = 0; i < 10; i++){
chars[i] = rand()%25 + 97;
x[i] = rand()%30;
y[i] = 0;
//y[i] = -(rand()%4);
}
while (true){
clear();
ch = wgetch(stdscr);
for (int i = 0; i < 10; i++){
mvwdelch(stdscr,y[i]-1,x[i]);//delete char's prev. position
mvwaddch(stdscr, y[i], x[i], chars[i]);//add char's current position
if (ch == chars[i]){
mvwdelch(stdscr, y[i], x[i]);
chars[i] = rand()%25 + 97;
x[i] = rand()%30;
y[i] = 0;
}
}
if(time(0) >= (lastupdate + 1)){
for (int i = 0; i < 10; i++){
y[i]++;
}
lastupdate = time(NULL);
}
wmove(stdscr, 20, 0);
printw("your score is NULL. press ESC to exit");
scrollok(stdscr, TRUE);
wrefresh(stdscr);
}
endwin();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:添加代码
edit2:删除了一些不相关的调试代码
该clear手册页是开始的地方:
在
clear和wclear程序就像erase和werase,但他们也呼吁clearok,使屏幕上的下一个电话彻底清除wrefresh该窗口,并从头开始重新绘制。
该wgetch电话确实是wrefresh,这会导致重绘:
如果窗口不是焊盘,并且自上次调用 以来已被移动或修改
wrefresh,wrefresh则将在读取另一个字符之前调用。
的描述wrefresh不是那么简洁,但是“从头重新绘制”会导致闪烁,因为屏幕有一段时间是空的,然后是非空的。由于这个调用,那些快速交替:
nodelay(stdscr, TRUE);
Run Code Online (Sandbox Code Playgroud)
紧随wgetch()其后的clear()是隐含的wrefresh(). 从wgetch()手册页:
If the window is not a pad, and it has been moved or modified
since the last call to wrefresh, wrefresh will be called before
another character is read.
Run Code Online (Sandbox Code Playgroud)