_getch 似乎暂停了我的程序

Posted

技术标签:

【中文标题】_getch 似乎暂停了我的程序【英文标题】:_getch is seeming to pause my program 【发布时间】:2015-01-24 05:51:29 【问题描述】:

标题非常具有描述性。基本上,我在 C++ 的控制台窗口中制作 Space Invaders,它被称为 ASCII Invaders。除了一个主要问题,我似乎让游戏中的所有内容都运行良好,_getch 正在暂停程序。我调用 _kbhit 检查玩家是否正在输入玩家输入,如果是,我使用 _getch 获取密钥并正确操作。玩家左/右移动就好了,但是当玩家按下“空格”或射击时,程序会暂停,直到你再次按下“空格”,此时它也会射击。

显然玩家不希望在游戏中出现这种情况。所以很想知道如何解决它。这里是它的名字:

/***************************************/
/*          move_player();             */
/*      Calculates player movement     */
/*Returns weather or not toQuitTheGame */
/***************************************/
bool move_player()

    bool ret = false;
    //If a key is pressed
    if (_kbhit())
    
        //Get key
        _getch();
        int key = _getch();
        //Check is the player moves left
        if (key == LEFT && object_handle.player_obj.x > 0)
        
            //Move left
            object_handle.player_obj.x -= 1;
        

        //Check is the player moves right
        if (key == RIGHT && object_handle.player_obj.x < 79)
        
            //Move right
            object_handle.player_obj.x += 1;
        

        //Check is the player is shooting
        if (key == SHOOT)
        
            //shoot by creating the bullet above the player
            object_handle.bullet_obj.x = object_handle.player_obj.x;
            object_handle.bullet_obj.y = object_handle.player_obj.y - 1;
            object_handle.bullet_obj.active = true;
        

        //Weather or not to kill the program
        if (key == VK_ESCAPE)
        
            ret = true;
        
        else
        
            ret = false;
        
    
    return ret;

作为旁注,如果您只是滚动浏览并思考“这是很多代码......我不想处理这个。” (我有时会这样做 - 不是在挑剔你)请注意这不是很多,我只是使用了很多 cmets 和很多空白。

如果你想知道,这里是整个“main”函数。

int main()

    bool quit = false;
    object_handle.set_info();

    //Display main manu
    menu();

    //Main game loop
    while(!quit)
    
        //Update past object variables
        object_handle.xy_update();

        //Calculate player movements
        quit = move_player();

        //Calculate bullet movements
        handle_objects();

        //Finally, update the screen
        screen_update();

        //DEBUG CODE
        debug();

        //Display score/stats
        stats();

        //Wait a given time before continuing the loop
        Sleep(INTERVAL);
    
    cout << "\n\n\n\n\nBye" << endl;
    Sleep(1000);
    return 0;

我已经包含了所有正确的库,没有编译错误。

哦,是的,在我忘记之前。以下是常量:

/******************CONSTANTS********************/
const int ENEMY_COUNT   = 15;
const int INTERVAL      = 250;
const int LEFT          = 75;
const int RIGHT         = 77;
const int SHOOT         = VK_SPACE;
const int BULLET_SPEED  = 8;
/***********************************************/

非常感谢任何帮助!

【问题讨论】:

你为什么要调用 _getch() 两次? 您必须调用它两次才能接收箭头键,但您可以检测到它并且只能有条件地执行此操作。如in this question/answer 所述,使用 ReadConsoleInput 可能会更好。 【参考方案1】:

如the documentation When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code. 中所述

因此,您需要检查返回的内容以确定是否应该再次调用该函数。

这是一个您应该能够适应您的需求的示例:

#include <conio.h>
#include <iostream>

int main()

    std::cout << "Type stuff, press x to quit.\n";
    int count = 0;
    for(;;)
    
        //To show the loop isn't blocked
        if((++count % 1000) == 0)
        
            std::cout << ".";
        
        if(_kbhit())
        
            int key = _getch();
            if(key == 0 || key == 0xE0)
            
                key = _getch();
            
            std::cout << "\nKeycode: " << key << "\n";
            if(key == 'x')
            
                break;
            
        
    
    return 0;

您也可以考虑使用ReadConsoleInput 系列函数,因为它为您提供了更多的灵活性。这是example from MSDN。

【讨论】:

【参考方案2】:

尝试改变:

_getch();
int key = _getch();

到:

int key = _getch();

在您的 move_player 函数中。

【讨论】:

【参考方案3】:

当你调用_getch() 两次,第一次,它不记录键,只是挂在那里,直到你再次按下键,因为那时_getch() 被分配给变量key。因此,您应该删除 move_player() 函数中的杂散 _getch()

正如@RetiredNinja 提到的,您确实需要拨打_getch() 两次,因此您需要检查第一个_getch() 以确定您是否按下了字母 键,或者特殊键。

【讨论】:

谢谢你们!有效。我在某个地方读到了你需要调用它两次的地方,所以我想我应该多读一点。 您确实需要调用它两次才能接收一些键,包括箭头键。 @PaoloMazzonJr。如果有效,请接受答案。这样做将有助于问题的其他查看者。 我很抱歉,我很少使用 Stack Overflow,而且我不知道该怎么做。你介意告诉我吗? 只需按下 upvote-downvote 计数器下方的灰色勾号使其变为绿色 :)

以上是关于_getch 似乎暂停了我的程序的主要内容,如果未能解决你的问题,请参考以下文章

getch() 等待 Enter 键? [复制]

我的简单 webview 应用程序现在在 googleplayconsole 上暂停,我该如何再次发布或删除它。? [关闭]

visual studio2012中 c语言编译出来的程序怎么暂停啊

诅咒库:为啥 getch() 清除我的屏幕?

iPhone内存泄漏似乎超出了我的控制

暂停一个while循环,而不是我在Python中的其余程序