键盘按键同时长按两个键时后按的键无效

0

我现在想做一个双人小游戏,我需要用awsd或者上下左右键控制两个人的行动,这样很大可能就会导致玩家长按上下左右键或者awsd键,然后现在出现了一个问题就是如果我两个人一起按键盘就会导致后按键盘那个动作无效,就是无法两个人同时长按键盘,我如果两边一起长按的话,只有一个会持续移动,但是如果此时我其中没有被移动的那个人重新按一下键盘,那么刚才持续移动那个会停止(实现过程就是下面的代码把printf换成我设计的人物移动代码,在这里只单独长按一个键可以正常移动)

但是我缩减代码的时候又遇到了个问题

下面是我缩减后的代码

我本来是打算弄一个,按W就显示w,按s就显示S,按上显示上,按下显示下……的可编译程序,但是运行之后按键没反应,然后我狂按键有时蹦出一个peek,然后无论我按什么键都没有任何输出,有的时候也会我刚一运行就蹦出来10个以上的peek,无论按什么键都无反应(补充:输出peek和message为出现问题后调试的过程)

#include <graphics.h>
#include <cstdio>
int main()
{
	initgraph(1260, 680, EX_SHOWCONSOLE);
	ExMessage mess;
	while(1) 
	{
		if (peekmessage(&mess, EX_KEY))
		{
			printf("peek");
			if(mess.message==WM_KEYDOWN)
			{
				printf("message");
				if((mess.vkcode == 'W'))
				{
					printf("w");
				}
				if((mess.vkcode == 'S'))
				{ 
					printf("s");
				}
				if((mess.vkcode == 'A'))
				{
					printf("a");
				}
				if((mess.vkcode == 'D'))
				{
					printf("d");
				}
				if((mess.vkcode == VK_UP))
				{
					printf("up");
				}
				if((mess.vkcode == VK_DOWN))
				{
					printf("down");
				}
				if((mess.vkcode == VK_LEFT))
				{
					printf("left");
				}
				if((mess.vkcode == VK_RIGHT))
				{
					printf("right");
				}
			}
		}
	}
	return 0;
}
ava
有毒

2022-9-12

1

首先,受硬件限制,每个键盘允许同时按下的按键数量是有限制的(不同键盘限制不同),通常键盘可以同时按下 3 个按键,再多了不一定可以同时处理(取决于按了哪些按键)。

其次,按键消息与字符消息不同,按键消息主要是判断一个按键何时按下、何时弹起。所以通常,同时判断成员 prevdown 可以知道该按键的按下或弹起状态。

在你的代码基础上,我做了若干修改,以下代码可以在你按下某个键的同时,仍然可以处理其它按键的按下消息。

// 程序名称:EasyX 同时按下多个按键测试
// 编译环境:VC6、VC2022,EasyX_20220901
// 作  者:慢羊羊(yw80@qq.com)
//
#include <graphics.h>
#include <stdio.h>

int main()
{
	initgraph(640, 480, EX_SHOWCONSOLE);
	ExMessage m;

	while(1) 
	{
		if (peekmessage(&m, EX_KEY))
		{
			if (m.message==WM_KEYDOWN && m.prevdown == false)
			{
				switch(m.vkcode)
				{
					case 'W':		printf(" [w] ");		break;
					case 'S':		printf(" [s] ");		break;
					case 'A':		printf(" [a] ");		break;
					case 'D':		printf(" [d] ");		break;
					case VK_UP:		printf(" [up] ");		break;
					case VK_DOWN:	printf(" [down] ");		break;
					case VK_LEFT:	printf(" [left] ");		break;
					case VK_RIGHT:	printf(" [right] ");	break;
				}
			}
			else if (m.message==WM_KEYUP && m.prevdown == true)
			{
				switch(m.vkcode)
				{
					case 'W':		printf(" <w> ");		break;
					case 'S':		printf(" <s> ");		break;
					case 'A':		printf(" <a> ");		break;
					case 'D':		printf(" <d> ");		break;
					case VK_UP:		printf(" <up> ");		break;
					case VK_DOWN:	printf(" <down> ");		break;
					case VK_LEFT:	printf(" <left> ");		break;
					case VK_RIGHT:	printf(" <right> ");	break;
				}
			}
		}
		Sleep(20);
	}
	return 0;
}
ava
慢羊羊

2022-9-13

0

用 windows.h 头件里的 API 异步输入函数 GetAsyncKeyState 能识别两个按键按下的情况,通常用于双人游戏的按键开发。

为什么要用大写的 W 呢?用小写他不香吗?在 C 语言里大小写,根本不是同一个东西,你可能是按了小写的 w,但是你代码里用的是大写的 W,你把你的输入法切换成大写,再去按试试?

ava
随波逐流

2022-9-12

按键消息与字符消息不同。“键码”不区分大小写,'A' 表示的就是这个按键,与这个按键代表的是大写还是小写无关。字符消息才会区分大小写。 -  慢羊羊  2022-9-13
技术讨论社区