2012-09-24 56 views
1

我使用Ncurses庫在C++中製作Pacman。我可以用我的代碼移動Pacman,但我想移動它,以便即使在我不按任何鍵時pacman仍在移動,並且當我按另一個方向鍵時,它會改變方向。現在,當我按下按鍵時,pacman只需要一步。在pacman向那個方向移動之前,我還必須按兩次或三次按鍵。即使沒有按下按鍵,我如何在屏幕上發生什麼?

if (ch==KEY_LEFT) 
{ 
    int b,row,column; 
    getyx(stdscr,row,column); 
    int h; 
    do // do-whileloop to move the pacman left until it hits the wall 
    { 
     column-=1; 
     mvprintw(row,column,">"); //print the ">" symbol 
     refresh(); 
     waitf(0.1);  //this pauses the game for 0.1sec 
     attron(COLOR_PAIR(1));  
     mvprintw(row,column,">"); 
     attroff(COLOR_PAIR(1)); 
     refresh(); 
     waitf(0.1); 
     mvprintw(row,(b),"O"); //showing the open mouth of pacman 
     refresh(); 
     waitf(0.1); 
     attron(COLOR_PAIR(1));a 
     mvprintw(row,column,"O"); 
     attroff(COLOR_PAIR(1)); 
     h = getch(); 
    } 
    while(h == KEY_LEFT); 
} 

right = getch(); 

循環向右移動在if條件

up = getch(); 

循環,在if條件

down = getch(); 

接力拉昇在一個if條件下移動。

+0

放置這樣一個條件,當用戶移動pacman時,它會進入一個循環並停下來,只有當它到達牆壁時纔等待下一條指令。 –

+0

但我希望只要按下另一個鍵,pacman就會改變它的方向。 – User14229754

回答

0

我建議你看一看的model-view-controller模型,它會幫助你這個問題,所有如果你繼續你的程序是這樣,你將有其他問題。

編輯:快捷

要將你吃豆子不斷,您將需要一個單獨的線程來控制它,讓它移動。看看pthreads吧。

如果您只保留用戶輸入到程序的主運行循環中,那麼您必須按幾次按鍵的問題也會消失(這裏的問題是處理器必須在getch ()行,否則不會被檢測到

+2

這個答案太寬泛了,它並沒有真正回答這個問題。 – Dialecticus

+0

我是初學者,我缺乏時間。請問你能告訴我一些其他的解決方案嗎? – User14229754

+0

用快捷方式編輯 – Minion91

5

標準解決方案是finite-state machine。該字符有六種可能的狀態:站立,向上移動,向右移動,向下移動,移動離開了,死了。而不是一個按鍵直接移動的字符,該按鍵應該改變人物的狀態。

在這樣一個小的應用程序,而不是實現一個非常靈活鰭ITE狀態機,你可以用一個非常簡單的實現爲這樣:

enum PlayerState { 
    Standing, 
    MovingUp, 
    MovingRight, 
    MovingDown, 
    MovingLeft, 
    Dead 
}; 

然後,你的遊戲循環中,您可以添加一個非常簡單的狀態檢查,然後花費的框架適當的行動。

switch(state) { 
case Standing: 
    break; 
case MovingUp: 
    player.PositionY += 1; 
    break; 
// ... 
} 

最後一步是勾選輸入,這取決於您檢索輸入的方法。使用回調,一個例子是:

void KeyDown(Key k) { 
    switch(k) { 
    case UpArrow: 
     if(state != Dead) 
      state = MovingUp; 
     break; 
    case RightArrow: 
     if(state != Dead) 
      state = MovingRight; 
    // ... 
    } 
} 

你可以看到爲什麼在一個較大的項目,以實施更靈活的有限狀態機也將是重要的,但我希望這個例子給你一個易於理解的想法。直到一些鍵被按下

1

功能getch被阻止。如果您不希望被阻止,請在getch之前致電_kbhit,以確保輸入緩衝區中有東西。

編輯:看看ncurses的功能nodelaycbreak。他們啓用異步輸入。

+0

我不能在ncurses中使用kbhit()。 – User14229754

+0

你在使用什麼操作系統,以及使用什麼編譯器? – Dialecticus

+0

g ++編譯器。我使用putty軟件連接我的大學服務器。 – User14229754

3

您需要一個等效的kbhit,即。一個非阻塞的getch。這真的給瞭解決方案,在輸入上設置O_NONBLOCK。看一個例子here。一旦你有了這個,只需連續循環,只需檢查鍵擊,不用等待實際的按鍵。

+0

對於O_NONBLOCK來說是+1,因爲我已經觸及了這些C API。 –

0

這是很容易
每個方向做4功能 和作用,把其中獲得通過的kbhit激活其他3個方向函數內。

並放置一個else語句,如果你沒有按下按鈕(例如(!kbhit()); 然後把所有這些放在一個循環中。


如果你對所有的方向功能都這樣做,你應該能夠得到理想的結果。

+0

這個巨大的,醜陋的代碼轉儲不是一個有用的「答案」。 – Blastfurnace

+0

其他答案至少試圖解決這個問題並提供具體的解決方案。另一方面,你從你自己的(封閉的)問題中粘貼相同的格式不正確的代碼,而沒有解釋或指導。請看看其他的問題和答案,以瞭解網站的工作原理。不要拿這個人,我知道你可以做得更好。乾杯。 – Blastfurnace

+0

我不知道爲什麼every1一直說它嚴重格式化我怎麼能讓它更好? –

相關問題