C ++控制台游戏输入&&刷新功能

时间:2010-10-28 09:03:50

标签: c++ input game-engine

我正在写一个小型的控制台冒险游戏,我遇到了一些问题 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 个答案:

答案 0 :(得分: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');

答案 1 :(得分:2)

  1. 代码在整个代码中应该只有一个getch()(如果可能),在开关内部,您可以为每个输入执行操作。因此,它是在循环内部切换,而不是在交换机内部的循环。像这样:

    while((ch = getch())!='q') {   开关(ch)   {   案例'a':     往左走();     打破;   ...   } }

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

答案 2 :(得分:1)

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

答案 3 :(得分: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();
   }
}

这样,在计算之前您总是会有某种输入值,然后您可以进行绘制(+调试起来更容易;))