ncurses clear() 导致闪烁
ncurses clear() causes flickering
我正在将 ncurses 用于我正在制作的打字游戏。字母从屏幕上掉下来,您必须在它们到达底部之前输入它们。它工作得很好,省去了一个问题。清除 window(使用 clear())会使输出闪烁。我将 clear() 放在循环的最开始,将 wrefresh() 放在最后。难道它不应该等待'til 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;
}
编辑:添加代码
edit2: 删除了一些不相关的调试代码
紧接在 clear()
之后的 wgetch()
执行隐含的 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.
clear
手册页是起点:
The clear
and wclear
routines are like erase
and werase
, but they also
call clearok, so that the screen is cleared completely on the next call
to wrefresh
for that window and repainted from scratch.
wgetch
调用执行 wrefresh
,这会导致重新绘制:
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.
wrefresh
的描述没有那么简洁,但是"repainting from scratch"会导致闪烁,因为屏幕有一段时间是空的,然后是非空的。由于这个电话,那些迅速交替:
nodelay(stdscr, TRUE);
我建议只使用 erase() 而不是 clear()
clear 也会自动调用 clearok()。
我正在将 ncurses 用于我正在制作的打字游戏。字母从屏幕上掉下来,您必须在它们到达底部之前输入它们。它工作得很好,省去了一个问题。清除 window(使用 clear())会使输出闪烁。我将 clear() 放在循环的最开始,将 wrefresh() 放在最后。难道它不应该等待'til 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;
}
编辑:添加代码
edit2: 删除了一些不相关的调试代码
紧接在 clear()
之后的 wgetch()
执行隐含的 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.
clear
手册页是起点:
The
clear
andwclear
routines are likeerase
andwerase
, but they also call clearok, so that the screen is cleared completely on the next call towrefresh
for that window and repainted from scratch.
wgetch
调用执行 wrefresh
,这会导致重新绘制:
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.
wrefresh
的描述没有那么简洁,但是"repainting from scratch"会导致闪烁,因为屏幕有一段时间是空的,然后是非空的。由于这个电话,那些迅速交替:
nodelay(stdscr, TRUE);
我建议只使用 erase() 而不是 clear() clear 也会自动调用 clearok()。