2010-10-28 226 views
2

我正在寫一個小型控制檯冒險遊戲,我遇到了一些問題。
1.輸入有點遲緩,我使用while循環(while(getch()=='w'))。第一次按下某個鍵後,沒有任何事情發生(必須按兩下),並且如果您切換方向(按A/D/S鍵),它也不會在第一次響應。如果你拿着鑰匙,它可以正常工作。這怎麼解決?
2.這是我用來刷新遊戲的功能(當按下一個鍵渲染遊戲場景):C++控制檯遊戲輸入&&刷新功能

void refresh(char map[Y][X]) 
{ 
    system("cls"); 
    for (int i = 0; i<UP; i++) 
    { 
     cout<<endl; 
    } 
    for (int i = 0; i<Y; i++) 
    { 
     for (int k = 0; k<LEFT; k++) 
     { 
      cout<<" "; 
     } 
     for (int j = 0; j<X; j++) 
     { 
      cout<<map[i][j]; 
     } 
     cout<<endl; 
    } 
} 

當我使用這個函數一次,它的確定,但是當他們鍵被按下或持有多時間 - 遊戲場開始閃爍。我認爲我只需要重繪一部分場地(進行改變/移動的場地),而不是整個場地。你能提供任何想法如何做到這一點?

輸入的示例代碼:

while(getch() == 'w') 
    { 
     if (map[y-1][x]!= WALL) 
     { 
     map[y-1][x] = CHARACTER; 
     map [y][x] = ' '; 
     y--; 
     refresh(map); 
     Sleep(SPEED); // this is unnecessary, SPEED is 0, I just kept it for tests 
     } 
    } 

基本上,主要功能如下:

int main() 
{ 
    (...) Variables (...) 
    generateMap(FROM FILE); 
    refresh(); // First initialization of the field 
    while (getch() != 'q') // While not quitting 
    { 
    while(getch() == 'w') 
    { 
     if (THE FIELD ABOVE IS NOT OCCUPIED) 
     { 
      setSomeVariables(); 
      refresh(THE GAMEFIELD); 
     } 
    } 
    } 
    while(getch() == 's') 
    { 
     if (THE FIELD BELOW IS NOT OCCUPIED) 
     { 
      setSomeVariables(); 
      refresh(THE GAMEFIELD); 
     } 
    } 
    } 
    while(getch() == 'a') 
    { 
     if (THE FIELD ON THE LEFT IS NOT OCCUPIED) 
     { 
      setSomeVariables(); 
      refresh(THE GAMEFIELD); 
     } 
    } 
    } 
    while(getch() == 'd') 
    { 
     if (THE FIELD ON THE RIGHT IS NOT OCCUPIED) 
     { 
      setSomeVariables(); 
      refresh(THE GAMEFIELD); 
     } 
    } 
    } 
    return 0; 
} 
+0

'getch()'第一次返回的值是多少? – Vlad 2010-10-28 09:10:14

+0

第一次它不返回任何東西(循環不運行),我已經添加了上面的代碼。 – Winis 2010-10-28 12:12:23

回答

3

不要使用system("cls"),它實在是太慢了,而是設置在屏幕的開頭用下面的代碼光標:

COORD cur = {0, 0}; 
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cur); 

你應該叫getch()只有一次在環,像這樣:

char key; 

do 
{ 
    key = getch(); 

    if(key == 'w') 
    { 
     //do something 
    } 

    //the other if statements 

}while(key != 'q'); 
+0

這些功能來自哪個庫? – luqui 2010-10-28 11:57:55

+0

@luqui Windows SDK – Dialecticus 2010-10-28 12:02:04

+0

你必須包含windows.h – Flagbug 2010-10-28 12:04:43

2
  1. 代碼應該只具有一個的getch()在整個代碼(如果可能的話),並在交換機內部爲每個輸入執行操作。所以,它是在循環內切換的,而不是在開關內部循環。是這樣的:

    而((CH =的getch())= 'Q'!) { 開關(CH) { 殼體 'A': GoLeft(); 休息; ... }}

  2. 有一個名爲ncurses,你可以用它來移動光標在屏幕上,並在任何地方寫東西的庫。

+0

1.我已經添加了代碼。 2.謝謝,如果沒有其他選擇,我會使用ncurses,但我想堅持默認庫。 – Winis 2010-10-28 12:08:17

+0

沒有用於顯示繪圖的默認庫,因爲在某些硬件中可能根本沒有顯示。我認爲這不是完整的相關代碼。代碼中有多個getch嗎? – Dialecticus 2010-10-28 12:18:49

+0

是的,我有5個(W,A,S,D代表控件,Q代表退出)。 我應該粘貼整個代碼嗎?大多數變量都不是英文的,所以理解其中的一些可能會很複雜。 – Winis 2010-10-28 12:42:27

1

它看起來像你的問題是多次調用getch()。只有一個循環,每循環調用一次getch(),並存儲結果。對每個循環的迭代測試每個值(q,w,s,...)的結果。

+0

謝謝!你和flagbug的解決方案工作,如果可能的話,我會接受這兩個答案。 – Winis 2010-10-28 14:59:32

+0

你仍然可以upvote;) – luke 2010-10-28 15:52:32

+0

我不能 - 它需要15聲望:/ – Winis 2010-10-28 18:58:25