ncurses clear()导致闪烁

时间:2018-02-02 00:08:48

标签: 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;
}

编辑:添加代码

edit2:删除了一些不相关的调试代码

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

clear手册页是开始的地方:

  

clear wclear 例程就像 erase {{ 1}} ,但他们也是   调用clearok,以便在下次通话时完全清除屏幕   该窗口的 werase 从头重新粉刷

wgetch调用 wrefresh 会导致重新绘制:

  

如果窗口不是打击垫,并且它已被移动或修改过          最后一次致电 wrefresh wrefresh 将在另一个角色之前调用          正在阅读。

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

wrefresh

答案 2 :(得分:1)

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.