因此,我最近发现了curses(特别是PDcurses),现在就开始讨论它。现在,我正在尝试用它编写一个小型的太空射击游戏,到目前为止,它在渲染和获取菜单类型输入方面都工作得很好,但是现在当我进入游戏时,我注意到按键重复对于 Action 类游戏。我需要能够按住键并在键按下的每个帧中移动化身。我知道如何使用普通的Win32应用程序来执行此操作,但是我没有窗口,因此没有wndproc,并且我无法控制控制台收到的消息:/

我不希望这是诅咒要解决的事情,尽管如果可以的话,那真是太棒了,我真的只是在寻找一种可以很好地解决诅咒的变通方法。

我尝试了cbreak(),nodelay()和raw()无济于事。

附加信息:

  • Microsoft Visual Studio 2010最终版
  • PDcurses 3.4,来自预构建的二进制文件
  • Windows 7 x64 Ultimate
  • 最佳答案

    这远不是一个完整的解决方案,我不知道它将如何与PDCurses交互,但这是一种尝试:

    总之,使用GetStdHandle()捕获控制台的句柄,使用SetConsoleMode()将其配置为原始读取,然后使用ReadConsoleInput()一次读取一个键。我使用std::set跟踪当前按下的键,因此忽略重复。

    #include "stdafx.h"
    #include <Windows.h>
    #include <iostream>
    #include <cassert>
    #include <set>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        HANDLE h=GetStdHandle(STD_INPUT_HANDLE);
        DWORD mode;
        BOOL success;
        success=GetConsoleMode(h, &mode);
        assert(success);
        mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
        mode |= ENABLE_WINDOW_INPUT;
        success=SetConsoleMode(h, mode);
        assert(success);
    
        INPUT_RECORD buffer[10];
        std::set<WORD> keys_down;
        while (true)
        {
            DWORD count=0;
            success=ReadConsoleInput(h, buffer, 10, &count);
            if (!success)
            {
                continue;
            }
            for (size_t i=0;i<count;++i)
            {
                switch (buffer[i].EventType)
                {
                case KEY_EVENT:
                {
                    WORD keycode=buffer[i].Event.KeyEvent.wVirtualKeyCode;
                    if (buffer[i].Event.KeyEvent.bKeyDown)
                    {
                        if (keys_down.find(keycode)==keys_down.end())
                        {
                            std::cout<<"Key down: "<<keycode<<std::endl;
                            keys_down.insert(keycode);
                        }
                    }
                    else
                    {
                        if (keys_down.find(keycode)!=keys_down.end())
                        {
                            std::cout<<"Key up:"<<keycode<<std::endl;
                            keys_down.erase(keycode);
                        }
                    }
                    break;
                }
                default:
                    break;
                }
            }
        }
    }
    

    07-27 17:51