2

我正在编写一个小型控制台冒险游戏,但遇到了一些问题。
1. 输入有点滞后,我正在使用 while 循环( while(getch() == 'w') )。第一次按下某个键后,什么也没有发生(您必须按两次),如果您切换方向(按 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()在循环中只调用一次,如下所示:

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() (如果可能的话),并且在一个开关中,您可以为每个输入执行操作。所以,它是循环内的开关,而不是开关内的循环。像这样的东西:

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

  2. 有一个名为ncurses的库,您可以使用它在屏幕上移动光标,并在任何地方写入任何内容。

于 2010-10-28T09:15:12.300 回答
1

看起来您的问题是多次调用 getch() 。只有一个循环,每个循环调用一次 getch() 并存储结果。为循环的每次迭代测试每个值 (q, w, s, ...) 的结果。

于 2010-10-28T12:53:46.427 回答
0

我建议您按原样使用函数 input() :

void input()
{   if (GetKeyState('W') & 0x8000)    // That means when button "W" is pressed
       ... your code ... 
     // (changes global variables, or you can pass variables by reference)
}

没有任何 getch() 命令每次都会停止你的游戏。


您可以将它与 main() 中的 draw() 和 calculate()/refresh() 函数一起使用,例如:

int main()
{
   ... other part of code ...

   while (!gameover)
   {
      input();
      calculate();
      draw();
   }
}

这样在计算之前您将始终拥有某种输入值,然后您将绘制(+它更容易调试;))

于 2018-11-30T16:41:32.150 回答