ncurses clear()导致闪烁

Jer*_*emy 3 c++ ncurses

我正在使用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:删除了一些不相关的调试代码

小智 7

我建议只使用erase()而不是clear()clear也自动调用clearok().


Tho*_*key 6

clear手册页是开始的地方:

clearwclear程序就像erasewerase,但他们也呼吁clearok,使屏幕上的下一个电话彻底清除wrefresh该窗口,并从头开始重新绘制

wgetch电话确实是wrefresh,这会导致重绘:

如果窗口不是焊盘,并且自上次调用 以来已被移动或修改wrefreshwrefresh则将在读取另一个字符之前调用。

的描述wrefresh不是那么简洁,但是“从头重新绘制”会导致闪烁,因为屏幕有一段时间是空的,然后是非空的。由于这个调用,那些快速交替:

nodelay(stdscr, TRUE);
Run Code Online (Sandbox Code Playgroud)


Wil*_*ine 4

紧随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)