sleep () в приложении ncurses - PullRequest
4 голосов
/ 18 марта 2012

Я пытаюсь создать текстовую анимацию для приложения, созданного в ncurses.

Пользователь нажимает клавишу, выбирает направление, и объект в текстовой сетке должен перемещаться из одной ячейки сетки в следующую в заданном направлении, ожидая 500 мс, прежде чем он начнет двигаться.Код, который я использовал:

while (!checkcollisions(pos_f, input)) { // Checks if it can move to next grid
    pos_f = moveobject(pos_f, input, ".."); // Moves object to next cell
    usleep(50000);
}

Но когда я выполняю его, вместо того, чтобы двигаться, ждать и двигаться снова, он ждет долго, и объект внезапно появляется в последней ячейке сетки, не показывая анимация .

Это из-за того, как работают ncurses?Я уже пытался использовать другие решения, такие как функция остановки select ().

Ответы [ 3 ]

7 голосов
/ 18 марта 2012

Вам нужно позвонить refresh() (до usleep).


Обновление: новые сегменты кода, вставленные в пастбище (в нескольких комментариях), указывают на реальную проблему, такую ​​же, как в ncurses-refresh : смешивание stdscr (подразумевается в следующих двух вызовах) и getch и refresh с newwin и wrefresh.
Обновление 2: использование полного кода, плюс некоторый взлом, Я получил его на работу (для некоторого значения "работа", я явно не правильно вызываю printmap (), и я создал поддельный файл "карты").

Не присматриваясь, я простоизменил все вхождения getch() на wgetch(win.window), все mvprintw вызовы mvwprintw (чтобы использовать это же окно) и удалил хотя бы один ненужный getch / wgetch.Тогда суть проблемы:

                while (!checkcollisions(pos_f, input)) {
-                       pos_f = moveobject(pos_f, input, "..");
-                       // sleep + wrefresh(win.window) doesn't work, neither does refresh()
+                       struct position new_pos = moveobject(pos_f, input, "..");
+                       printmap(pos_f, new_pos);
+                       pos_f = new_pos;
+                       wrefresh(win.window);
+                       fflush(stdout);
+                       usleep(50000);
                }

Вышеупомянутый вызов printmap определенно неверен, но все же вам определенно нужно сделать что-то в цикле, чтобы изменить то, что в win.window (или stdscr или какое-то другое окно, которое вы открыли, или что-то еще);и затем вам нужно принудительно обновить его, и вывести вывод на стандартный вывод с помощью fflush(stdout) перед сном.

1 голос
/ 18 марта 2012

См. Принятый ответ здесь .Вы заставляете все блокировать с помощью getch, затем, как только getch разблокирован ключом, доступным для чтения, все движется, как вы ожидаете.

Ваш цикл должен выглядеть примерно так, используя код из ссылки...

while( !kbhit() )
{
     sleep( 500 ); // You get to determine how long to sleep here...
}

input = getch();

// Your old logic, roughly, goes here.
1 голос
/ 18 марта 2012

Попробуйте что-то вроде

while (!checkcollisions(pos_f, input)) { // Checks if it can move to next grid
    pos_f = moveobject(pos_f, input, ".."); // Moves object to next cell
    refresh();
    napms(200);
}
...