2016-12-03 59 views
0

我正在爲一個類製作2D地牢爬蟲類遊戲。我正在嘗試接收用戶輸入,而不需要按下回車鍵。具體來說,我想使用w a s作爲方向鍵來移動2D數組。Getch()與linux中的顯示函數不兼容C++

我試過使用ncurses庫,但它目前與我的顯示功能(我相信當使用endl)messes。

正常顯示我的董事會將是這樣的:
XXX
XXX
XXX

但在使用時的getch()從ncurses庫我的板是這樣的:
XXX
..... .xxx
............ xxx

有沒有辦法從curses庫中使用getch()而不干擾我的打印功能?

void ParkBoard::print() { 
displayMessage(); 
for (int i = 0; i < getSize(); i++) { 
    cout << " "; 
    for (int j = 0; j < getSize(); j++) { 
     if (j == 0) { 
      parkBoard[i][j]->display(); 
     } 
     else { 
      cout << " "; 
      parkBoard[i][j]->display(); 
     } 
    } 
    cout << endl; 
} 

回答

2

ncurses期望它完全控制顯示終端。您正在使用ncurses進行輸入,但仍會將輸出噴到std::cout

這是行不通的。至少不是沒有大的黑客攻擊。

ncurses是一個全部或沒有處理。您可以使用ncurses進行輸入,也可以使用終端輸出,或者完全使用其他功能。

但還有一個更簡單的解決方案,因爲你正在試圖做的一切是「接收用戶輸入,而不需要輸入鍵被按下」:

  1. 只要把文件描述符0非阻塞模式,並且使用read()從fd 0讀取(因爲std::cin在從非阻塞文件描述符讀取時將需要太多保姆)。

查看fcntl(2)說明書頁面,並搜索O_NONBLOCK。然後:

  1. 通過關閉ICANON標誌將終端置於非規範模式。請參閱termios(3)手冊頁。這就是ncurses所做的,以訪問原始的擊鍵。

如果程序中止,您需要做一些工作才能將終端恢復到規範模式,以便以「理智」的終端模式返回到shell。

+0

我從來沒有使用過文件描述符。我想弄清楚如何設置它,但我有點失落。所以它不必從文件中讀取輸入,它可以只是擊鍵?此外,這是正確的設置:ssize_t讀(int fd,void * buf,size_t計數); – Kazuo

+1

你不必設置任何東西。文件描述符0是標準輸入,由進程繼承。 –

1

短:沒有

長:

詛咒寫入(默認情況下)到標準輸出,像cout。但是在一個程序中使用這兩個程序需要您切換I/O模式,並記住curses和cout的輸出緩衝區是不同的

當curses初始化時,它會更改終端的輸入和輸出模式,以允許讀取(輸入)單個字符並允許使用單獨的回車符和換行符(輸出)。 cout假定換行符(換行符)導致回車。當你使用curses時,情況並非如此。

當curses初始化時,它會保存一個終端輸入和輸出模式的副本,您可以使用詛咒電話reset_shell_modereset_prog_mode臨時切換到/。使用這些而不是臨時的termios調用來避免混淆詛咒。

除了終端模式外,還有輸出緩衝地址。如果你已經使用cout寫入了標準輸出,則在切換回詛咒之前刷新該流。從curses切換到cout, a refresh在curses中確保屏幕處於已知狀態。

雖然可以使用newterm指定的實際輸出流的詛咒(並使其從coutcin不同的),你仍然必須使用詛咒接口可靠使用圖書館。