2

私は小さなコンソール アドベンチャー ゲームを書いていますが、いくつかの問題に直面しました。
1. 入力がちょっと遅いです。while ループ ( while(getch() == 'w') ) を使用しています。最初にキーを押した後は何も起こりません (キーを 2 回押す必要があります)。方向を切り替えても (キー A/D/S を押します)、最初は反応しません。キーを持っていれば問題なく動作します。これはどのように修正できますか?
2.ゲームをリフレッシュするために使用する関数は次のとおりです(キーが押されたときにゲームシーンをレンダリングします):

    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;
}
4

4 に答える 4

4

は使用しないでくださいsystem("cls")。非常に低速です。代わりに、次のコードを使用してカーソルを画面の先頭に設定します。

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

getch()次のように、ループ内で 1 回だけ呼び出す必要があります。

char key;

do
{
    key = getch();

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

    //the other if statements

}while(key != 'q');
于 2010-10-28T09:46:33.547 に答える
2
  1. コードには、コード全体 (可能であれば) に getch() を 1 つだけ含める必要があり、スイッチ内では各入力に対してアクションを実行します。したがって、ループ内のスイッチであり、スイッチ内のループではありません。このようなもの:

    while ((ch = getch()) != 'q') { switch (ch) { case 'a': GoLeft(); 壊す; ... } }

  2. ncursesと呼ばれるライブラリがあり、これを使用して画面上でカーソルを移動したり、どこにでも何かを書き込んだりできます。

于 2010-10-28T09:15:12.300 に答える
1

問題が getch() を複数回呼び出しているようです。ループは 1 つだけにして、ループごとに 1 回 getch() を呼び出し、結果を格納します。ループの反復ごとに、各値 (q、w、s、...) についてその結果をテストします。

于 2010-10-28T12:53:46.427 に答える