【发布时间】:2014-03-27 00:09:28
【问题描述】:
好的,开始这个话题我想说我对编码比较陌生。话虽如此,如果问题太模糊而无法理解,我深表歉意。
以下代码来自我为 Win32 制作的第一个真正的 c++ 程序。函数playerMove 将玩家图标移动到屏幕上的新位置,同时用 X 替换旧位置。
我不知道为什么,但每当我按下任何键以引起移动时,它都会执行两次操作。我不确定我读取输入缓冲区的方式是什么,但我想知道是否有一个我刚刚错过的简单解释。我在每个案例的末尾都添加了FlushConsoleInputBuffer,以防出现问题,但这似乎并没有解决问题。
void playerMove()
{
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD NumInputs = 0;
DWORD InputsRead = 0;
bool running = true;
INPUT_RECORD irInput;
GetNumberOfConsoleInputEvents(hInput, &NumInputs);
while(running)
{
ReadConsoleInput(hInput, &irInput, 1, &InputsRead);
//std::cout << irInput.Event.KeyEvent.wVirtualKeyCode << std::endl;
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
COORD coordDest;
switch(irInput.Event.KeyEvent.wVirtualKeyCode)
{
case M_KEY:
FlushConsoleInputBuffer(hInput);
displayMenu();
//Opens the menu
break;
case VK_LEFT:
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
coordDest.X=xcoord;
coordDest.Y=ycoord;
SetConsoleCursorPosition(hStdout, coordDest);
cout<<'X';
coordDest.X=(xcoord-1);
SetConsoleCursorPosition(hStdout, coordDest);
SetColor(11);
cout<<'@';
SetColor(7);
xcoord--;
FlushConsoleInputBuffer(hInput);
// move it left
break;
case VK_UP:
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
coordDest.X=xcoord;
coordDest.Y=ycoord;
SetConsoleCursorPosition(hStdout, coordDest);
cout<<'X';
coordDest.Y=(ycoord-1);
SetConsoleCursorPosition(hStdout, coordDest);
SetColor(11);
cout<<'@';
SetColor(7);
ycoord--;
FlushConsoleInputBuffer(hInput);
// move it up
break;
case VK_RIGHT:
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
coordDest.X=xcoord;
coordDest.Y=ycoord;
SetConsoleCursorPosition(hStdout, coordDest);
cout<<'X';
coordDest.X=(xcoord+1);
SetConsoleCursorPosition(hStdout, coordDest);
SetColor(11);
cout<<'@';
SetColor(7);
xcoord++;
FlushConsoleInputBuffer(hInput);
// move it right
break;
case VK_DOWN:
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
coordDest.X=xcoord;
coordDest.Y=ycoord;
SetConsoleCursorPosition(hStdout, coordDest);
cout<<'X';
coordDest.Y=(ycoord+1);
SetConsoleCursorPosition(hStdout, coordDest);
SetColor(11);
cout<<'@';
SetColor(7);
ycoord++;
FlushConsoleInputBuffer(hInput);
// move it down
break;
}
}
}
【问题讨论】:
-
确实有两个按键通知。跌的时候一个,涨的时候一个。您忘记查看KEY_EVENT_RECORD.bKeyDown member。您还忘记检查 INPUT_RECORD.EventType,您从这个 winapi 函数获得的不仅仅是键盘输入。
-
@πάνταῥεῖ 这只是我代码的一部分,我在其中使用更多的 winapi 以更易于编写和理解的方式操作控制台。如前所述,我是一名新程序员,所以当我启动这个程序时“使用命名空间 std;”是我开始的,我一定会在完成之前修复它。
-
@HansPassant 谢谢汉斯的实际建议。你为我节省了数小时的搜索时间。现在已经很晚了,但我明天会尝试实施,我毫不怀疑它会起作用。
-
@πάνταῥεῖ,Windows API 并没有排除使用 C++。至于使用 C++ 流 I/O 与控制台交互,我认为这个问题中的代码说明了不这样做的一个很好的理由:C++ 标准库没有提供读取箭头键或在屏幕上移动光标的设施。
标签: c++ winapi windows-console