方法:当我们按住时,程序只执行一次? 我用C++做游戏控制台,我有个问题。当我按下空格键时,我在游戏中的赛车会跳起来。当我按住键盘时,我的车会跳很多次。我想:当我按住空格键时,我的车只跳一次

方法:当我们按住时,程序只执行一次? 我用C++做游戏控制台,我有个问题。当我按下空格键时,我在游戏中的赛车会跳起来。当我按住键盘时,我的车会跳很多次。我想:当我按住空格键时,我的车只跳一次,c++,winapi,C++,Winapi,如何做到这一点 我读过很多关于GetAsyncKeyState()的主题,但我不知道如何在游戏中使用它 if ( _kbhit() ) { char key = _getch(); if ((key == 75) && (car.position.x > 2)) { car.position.x -= 3; } else if ((key == 77) && (car.position.x

如何做到这一点

我读过很多关于
GetAsyncKeyState()
的主题,但我不知道如何在游戏中使用它

  if ( _kbhit() )

 {

    char key = _getch();

    if ((key == 75) && (car.position.x > 2))
    {
        car.position.x -= 3;
    }
    else if ((key == 77) && (car.position.x < 24))
    {
        car.position.x += 3;
    }
    else if ((key == 32) && (car.position.y > 2))
    {
        car.position.y -= 5;
    }
  }
if(_kbhit())
{
char key=_getch();
如果((键==75)和&(轿厢位置x>2))
{
轿厢位置x-=3;
}
如果((键==77)和&(轿厢位置x<24))
{
轿厢位置x+=3;
}
否则,如果((键==32)和(&(轿厢位置y>2))
{
轿厢位置y-=5;
}
}

下面我有一个示例软件,介绍了从输入流中“过滤”重复空间字符的一种可能方法

这个想法依赖于两个线程的使用

Thrd1从名为ssIn的stringstream中读取。(在代码中替换为cin。)

Thrd1(一个过滤器)检测并丢弃背对背的空间字符,并且只将第一个(多个空间字符中的)发送给thrd2

Thrd2-读取由thrd1填充的单个字符缓冲区,该缓冲区将永远看不到背对背的空格字符

两个THRD由一对信号量(不是互斥量)同步

在我的示例中,为了方便起见,我使用了我的Posix信号量版本。我不知道你是否有POSIX,但我相信你会很容易找到许多C++的信号灯在Web上可用,即使在SO中,而且大多数只使用C++的特性。
请注意,这只是一个测试。。。在“j”之后插入1000000空格的字母表。这不是一个托鲁夫测试。可能还有其他问题需要处理。我安装了一个对输入错误行为的严格处理程序。断言将帮助您识别问题

“thrd2”表示您在本例中的脚趾保持力。Thrd2接收经过过滤的流



对于100万个字符的输入,持续时间为120毫秒。

下面我有一个示例软件,介绍了从输入流中“过滤”重复空间字符的一种可能方法

这个想法依赖于两个线程的使用

Thrd1从名为ssIn的stringstream中读取。(在代码中替换为cin。)

Thrd1(一个过滤器)检测并丢弃背对背的空间字符,并且只将第一个(多个空间字符中的)发送给thrd2

Thrd2-读取由thrd1填充的单个字符缓冲区,该缓冲区将永远看不到背对背的空格字符

两个THRD由一对信号量(不是互斥量)同步

在我的示例中,为了方便起见,我使用了我的Posix信号量版本。我不知道你是否有POSIX,但我相信你会很容易找到许多C++的信号灯在Web上可用,即使在SO中,而且大多数只使用C++的特性。
请注意,这只是一个测试。。。在“j”之后插入1000000空格的字母表。这不是一个托鲁夫测试。可能还有其他问题需要处理。我安装了一个对输入错误行为的严格处理程序。断言将帮助您识别问题

“thrd2”表示您在本例中的脚趾保持力。Thrd2接收经过过滤的流



100万字符输入的持续时间为120毫秒。

正如@Remy Lebeau所指出的,您可以通过安装并过滤按下的键来获得重复计数

当然,为了简单起见,无需安装一个钩子,您可以在按住空格键时过滤重复消息。以下是您可以参考的示例:

case WM_KEYDOWN:
    if (wParam == VK_SPACE)
    {           
        if (!((HIWORD(lParam) & 0x4000) || (HIWORD(lParam) & 0x8000)))
        {
            isKeyHold = TRUE; // First time pressed
            OutputDebugString(TEXT("pressed !\n")); 
        }
        else if (isKeyHold && (HIWORD(lParam) & 0x4000))
        {
            OutputDebugString(TEXT("hold !\n")); 
            return 1; // Don't handle the message when the key is pressed and held.
        }
    }
    break;
case WM_KEYUP:
    if (wParam == VK_SPACE && isKeyHold)
    {
        isKeyHold = FALSE; // Clear the isKeyHold flag when release the key.
        OutputDebugString(TEXT("release !\n"));
    }
    break;

正如@Remy Lebeau指出的,通过安装并过滤按下的键,可以获得重复计数

当然,为了简单起见,无需安装一个钩子,您可以在按住空格键时过滤重复消息。以下是您可以参考的示例:

case WM_KEYDOWN:
    if (wParam == VK_SPACE)
    {           
        if (!((HIWORD(lParam) & 0x4000) || (HIWORD(lParam) & 0x8000)))
        {
            isKeyHold = TRUE; // First time pressed
            OutputDebugString(TEXT("pressed !\n")); 
        }
        else if (isKeyHold && (HIWORD(lParam) & 0x4000))
        {
            OutputDebugString(TEXT("hold !\n")); 
            return 1; // Don't handle the message when the key is pressed and held.
        }
    }
    break;
case WM_KEYUP:
    if (wParam == VK_SPACE && isKeyHold)
    {
        isKeyHold = FALSE; // Clear the isKeyHold flag when release the key.
        OutputDebugString(TEXT("release !\n"));
    }
    break;

您已经描述了期望的和观察到的行为。这很好。但是为了让你的问题有答案,你需要展示你用来获取密钥的代码。标准C++没有这个,所以你使用的是一些框架。我们猜不到。请张贴一个GATASYNCKESTATE()不是C++函数。找出你从哪里得到的,然后请你把问题贴在标签上。我可以在C++中包含并使用它,所以我用C++来标记我的问题。这是我第一次在StAdvOp溢出上添加一个问题,我很抱歉你真正需要的是密钥的重复计数器,但是在控制台应用程序中,你不能得到代码< > GETCHED()/<代码>。但是你确实可以在GUI应用程序中获得
WM_KEYDOWN
消息。因此,您可能需要通过
SetWindowsHookEx(WH\u keyboard\u LL)
使用低级键盘挂钩来接收按键通知及其重复计数。您已经描述了所需和观察到的行为。这很好。但是为了让你的问题有答案,你需要展示你用来获取密钥的代码。标准C++没有这个,所以你使用的是一些框架。我们猜不到。请张贴一个GATASYNCKESTATE()不是C++函数。找出你从哪里得到的,然后请你把问题贴在标签上。我可以在C++中包含并使用它,所以我用C++来标记我的问题。这是我第一次在StAdvOp溢出上添加一个问题,我很抱歉你真正需要的是密钥的重复计数器,但是在控制台应用程序中,你不能得到代码< > GETCHED()/<代码>。但是你确实可以在GUI应用程序中获得
WM_KEYDOWN
消息。因此,您可能需要通过
SetWindowsHookEx(WH\u keyboard\u LL)
使用一个低级键盘挂钩来接收按键和重复计数的通知。这是一个很好的主意,但OP实际上只是想禁用按键重复。它甚至不需要跨平台。不需要所有后期处理的东西。这是一个可爱的想法,但OP真的只是想禁用密钥重复。它甚至不需要跨平台。不需要所有那些后期处理的东西。
case WM_KEYDOWN:
    if (wParam == VK_SPACE)
    {           
        if (!((HIWORD(lParam) & 0x4000) || (HIWORD(lParam) & 0x8000)))
        {
            isKeyHold = TRUE; // First time pressed
            OutputDebugString(TEXT("pressed !\n")); 
        }
        else if (isKeyHold && (HIWORD(lParam) & 0x4000))
        {
            OutputDebugString(TEXT("hold !\n")); 
            return 1; // Don't handle the message when the key is pressed and held.
        }
    }
    break;
case WM_KEYUP:
    if (wParam == VK_SPACE && isKeyHold)
    {
        isKeyHold = FALSE; // Clear the isKeyHold flag when release the key.
        OutputDebugString(TEXT("release !\n"));
    }
    break;