游戏编程入门学习笔记31——菜单篇——虚拟键码到DirectInput键码的转换

更多的细节处理先放一边,接下来考虑关于操作键的全局变量如何设定问题,即如何保存再如何使用,这样也好明确该如何保存edit内的信息。

 

之前只是copy了《游戏编程入门》里的DirectInput按键处理函数,对其内部机制还没深入研究,于是重新理解相关代码。

DirectInput的键盘状态似乎储存在一个256字节空间的缓冲区中,每个键按虚拟码的排列顺序对应一个字节,具体顺序可在dinput.h中查看。用GetDeviceState取出缓冲区数据作判断处理,假如某字节的最高位为1,就表示处于按下状态,当然为0也就表示没按下。不管哪本教材甚至是DirectX的帮助文档,都没有说字节的其他七位用来干什么了,那我们也就不关心了,或许根本就没用处吧。

 

可截取的键盘消息蕴藏着虚拟键码信息,但是游戏中做按键判断时用的却是DirectInput键码。自定义操作键的最终目的是要拿去游戏循环里作命令判断用的,这时就需要做一个转换将二者联系起来。

最容易想到的方法是做一个查找表。但是上百个键一一对照抄写起来还是很麻烦的。

 

在热心网友青云同学提供的参考代码提示下,我发现了一个函数叫MapVirtualKey(),它的作用是在虚拟键码、(键盘)扫描码、字符间自动作转换。

这里有必要对三种码作一个说明:

1virtual-key code 虚拟码 

windows系统采用的键盘编码,会随WM_KEYDOWN等消息发送。

2DirectInput keyboard scan code  DirectInput键码(下文简称DIK码)

DirectInput的键盘编码,可作key[256]数组的下标使用判断按键状况,在dinput.h中可查阅。

3scan code 键盘扫描码

这玩意之前没怎么见过,完全是顺着MapVirtualKey函数摸出来的。百度了下,属于更底层的键盘编码,一共有三套set123,一般都转换为第一套使用。

 

然后我写了一个测试程序,按任意键均输出虚拟码转扫描码的结果的十进制和十六进制形式,来看看自己键盘所有键按下时转换函数给出的结果是多少。

测试结果给出一个令人振奋的结论:DIK码同键盘扫描码绝大部分是兼容的,而set1未包含的几个键,实际转换结果也同DIK一样。

仅仅有这么一些键需要注意:

1LWinRWinApp三个键实测扫描码为5B5C5D,而DIK码为DBDCDD

2,键盘中区的inserthome还有方向箭头等那十个键,扫描码同小键盘是完全重复的。但是虚拟键码和DIK码却都有区分,所以要单独处理。

小键盘的除号键亦如此。

3,左右ShiftCtrl,因为虚拟码相同,导致仅从键盘消息中是无法区分的。为节省时间,这里不进一步探讨区分识别方法。当程序中DirectInput检测到RShiftRCtrl时,统一当做相应左键被按下处理。

小键盘的enter键亦如此。检测到小键盘enter时,当做主ENTER处理。

4,右上方三个键PrScrnScroll LockPause一般不会有人使用,这里不作考虑。

5Alt键在程序中总是被菜单拦截,为了节省时间,这里不进一步考虑应对办法,直接默认不可用作操作键。

 

可以想到除非采取更聪明的办法,比如统一使用消息机制或是dirextx来处理键盘,不然要照顾到所有键盘解决兼容性问题的话,还是有很多头疼的工作要做的,不过这里不管了,以目前最常见的这种104键盘为准。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值