#c #ncurses
Вопрос:
Я пытаюсь написать такую программу, как nethack, с помощью ncurses. Программа работает отлично, рисует мне коробку и все идеально, не съедая большую часть моего процессора. После того, как я добавил while(true)
цикл, он не рисует мою коробку, и он съедает 100% моего процессора, когда я перемещаю своего «персонажа».
#include <iostream>
#include <curses.h>
int main(){
std::pair<int,int> csr_pos{1,1};
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
curs_set(0);
WINDOW *win = newwin(50,80,0,0);
if(has_colors()){
start_color();
init_pair(1,COLOR_CYAN,COLOR_BLACK);
init_pair(2,COLOR_RED,COLOR_BLACK);
init_pair(3,COLOR_WHITE,COLOR_RED);
init_pair(4,COLOR_YELLOW,COLOR_BLACK);
}
/*
wattron(win,COLOR_PAIR(1));
mvwaddch(win,25,41,'@');
wattroff(win,COLOR_PAIR(1));
*/
for(int i = 0; i<80; i ){
mvwaddch(win,0,i,'#');
mvwaddch(win,49,i,'#');
wrefresh(win);
}
for(int i = 1; i<49; i ){
mvwaddch(win,i,0,'#');
mvwaddch(win,i,79,'#');
wrefresh(win);
}
while(true){
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
int ch = getch();
if(ch==KEY_LEFT){
mvwaddch(win,csr_pos.first,csr_pos.second,' ');
csr_pos.second--;
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
}
if(ch==KEY_RIGHT){
mvwaddch(win,csr_pos.first,csr_pos.second,' ');
csr_pos.second ;
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
}
wrefresh(win);
}
}
Ответ №1:
nodelay(stdscr, TRUE);
Давайте посмотрим, что говорится об этом на странице руководства по проклятиям:
nodelay
The nodelay option causes getch to be a non-blocking call. If no input
is ready, getch returns ERR. If disabled (bf is FALSE), getch waits
until a key is pressed.
Если это не было ясно: в режиме getch
nodelay не ждет нажатия клавиши. Он немедленно возвращается.
Давайте посмотрим, что будет дальше делать показанный код:
while(true){
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
int ch = getch();
// ...
Таким образом, теперь это становится бесконечным циклом, связанным с процессором на 100%. getch
всегда возвращается немедленно. Если ни одна из двух клавиш, которые проверяет следующий код, не нажата, этот while
цикл немедленно запускается снова, и вы возвращаетесь к тому, с чего начали, снова и снова.
И именно по этой причине показанный код «съедает 100%» процессора.
nodelay
режим предназначен для использования с дополнительной логикой, которая poll()
действует до тех пор, select()
пока не будет нажата клавиша, и getch
вызывается только тогда, когда есть фактический ключ для чтения.
Комментарии:
1. Итак, я прокомментировал это
nodelay()
, это решило мою проблему с процессором, но я все еще не понимаю, почему моя коробка не рисуется.2. Это был бы еще один, не связанный с этим вопрос, который лучше рассмотреть в новом вопросе..
3. Ваше поле не нарисовано, потому что неявное обновление
stdscr
bygetch()
перезаписываетсяwin
. Измените его наwgetch(win)
.