VC++2010游戏开发随记之四十二 - 图文(4)

2020-02-21 11:24

四、精炼:DirectInput使用五步曲

上面讲解了洋洋洒洒七千字,信息量有些大,为了突出下重点,落实到一个字“用”上,让大家有的放矢,快速掌握DirectInput的使用方法。浅墨在这里依旧是来一个使用几步曲的归纳,主要以代码为载体,把上面讲得知识归纳一下。这回的DirectInput同样是五步曲。需要说明下的是,下面的代码是关于处理键盘消息的,而对于鼠标设备,需要改的地方非常少,也就是在第一步调用CreateDevice方法时GUID填

GUID_SysKeyboard,然后在第二步SetDataFormat中填c_dfDIKeyboard就可以了(相关知识上面我们有详细讲到)。对于其他设备。依然是改这两个地方,其他设备的GUID用EnumDevices枚举一下就知道了,废话也不多说,下面就开始DirectInput使用五步曲的讲解:

这五步曲分别是:

一、创键DirectInput接口和设备,简称创设备 二、设置数据格式和协作级别,简称设格式 三、获取设备控制权,简称拿权力 四、获取按键情况并做响应,简称取按键 五、释放控制权和接口对象,简称释对象

DirectInput使用五步曲载体代码:

[cpp] view plaincopyprint?

1. //首先是全局变量的定义

2. LPDIRECTINPUTDEVICE8 g_pKeyboardDevice = NULL; 3. char g_pKeyStateBuffer[256] ={0};

4. //--------------------------------------------------------------------------------------—----------------

5. //【DirectInput使用五步曲之一】,创键DirectInput接口和设备,简称创设备

6. //--------------------------------------------------------------------------------------—---------------- 7.

8. //创建DirectInput设备

9. DirectInput8Create(hInstance,0x0800, IID_IDirectInput8,(v

oid**)&g_pDirectInput, NULL);

10. g_pDirectInput->CreateDevice(GUID_SysKeyboard,&g_pKeyboa

rdDevice,NULL);

11. //--------------------------------------------------------------------------------------—----------------

12. //【DirectInput使用五步曲之二】,设置数据格式和协作级别,简称设格式 13. //--------------------------------------------------------------------------------------—---------------- 14. //设置数据格式和协作级别

15. g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard); 16. g_pKeyboardDevice->SetCooperativeLevel(hwnd,DISCL_FOREGR

OUND |DISCL_NONEXCLUSIVE); 17.

18. //--------------------------------------------------------------------------------------—----------------

19. //【DirectInput使用五步曲之三】,.获取设备控制权,简称拿权力

20. //--------------------------------------------------------------------------------------—---------------- 21. g_pKeyboardDevice->Acquire(); 22.

23. //--------------------------------------------------------------------------------------—----------------

24. //【DirectInput使用五步曲之四】,.获取按键情况并做响应,简称取按键 25. //--------------------------------------------------------------------------------------—---------------- 26. 27.

28. // 读取键盘输入

29. ::ZeroMemory(g_pKeyStateBuffer,sizeof(g_pKeyStateBuffer)

);

30. Device_Read(g_pKeyboardDevice,(LPVOID)g_pKeyStateBuffer,

sizeof(g_pKeyStateBuffer)); 31. //定义的全局函数

32. BOOL Device_Read(IDirectInputDevice8*pDIDevice, void* pBuffer, l

onglSize) 33. {

34. HRESULThr; 35. while(true) 36. {

37. pDIDevice->Poll(); // 轮询设备 38. pDIDevice->Acquire(); // 获取设备的控制

39. if(SUCCEEDED(hr = pDIDevice->GetDeviceState(lS

ize, pBuffer))) break;

40. if(hr !=DIERR_INPUTLOST || hr != DIERR_NOTACQ

UIRED) return FALSE;

41. if(FAILED(pDIDevice->Acquire())) return FALSE;

42. }

43. returnTRUE; 44. }

45. //然后就是用if判断并做响应了,如下面一句代码

46. if (g_pKeyStateBuffer[DIK_A] & 0x80)fPosX -= 0.005f; 47.

48. //--------------------------------------------------------------------------------------—----------------

49. //【DirectInput使用五步曲之五】,.释放控制权和接口对象,简称释对象 50. //--------------------------------------------------------------------------------------—---------------- 51. g_pKeyboardDevice->Unacquire(); 52. SAFE_RELEASE(g_pKeyboardDevice)

所以,上述DirectInput使用五步曲精炼总结起来就十五个字:

创设备,设格式,拿权力,取按键,释对象

五、DirectInput键盘按键键值总结

与一般的Windows应用程序相比,DirectInput处理键盘事件的方式是有很多独特之处的。首先,在我们写的游戏程序中,键盘主要并不是用于文字输入的,而是用于控制3D世界中人物,对象的运动,或者视角的变换等等。且在游戏程序中我们常常只需要知道具体是哪个键被按下,而忽略了该键所对应的字符。所以我们只需读取已按下键的扫描码就可以了。

另外,为了提高程序运行的效率,DirectInput并非使用Windows中的消息机制来读取键盘的状态,而是直接读取硬件的状态获取按键的扫描码的。 我们在按照流程创建好和打理好DirectInput之后,就能在程序中不断获取从键盘输入的那些键盘数据。而在程序中,我们需要定义一个大小为256字节的数组,其中的每一个字节都存储一个按键的状态,这样就可以保存256个按键的状态信息了。微软在DirectInput中为每个键都设置了一个对应的宏,这些宏都是以DIK_为前缀的。例如C键就定义为DIK_C,主键盘数字键8就对应DIK_8等等,下面就是浅墨对DirectInput键码做的一个总结表格,查起来非常方便: DirectInput键码 DIK_0~ DIK_9 DIK_A~ DIK_Z DIK_F1~ DIK_F15 DIK_NUMPAD0~ DIK_NUMPAD9 DIK_ESCAPE,DIK_TAB, DIK_BACK DIK_RETURN,DIK_SPACE,DIK_NUMBERENTER DIK_LSHIFT, DIK_RSHIFT DIK_LMENU, DIK_RMENU DIK_LALT, DIK_RALT DIK_LCONTROL, DIK_RCONTROL DIK_UPARROW, DIK_DOWNARROW DIK_LEFTARROW, DIK_RIGHTARROW DIK_HOME, DIK_DELETE, DIK_INSERT DIK_PRIOR, DIK_NEXT, DIK_END 说明 主键盘上数字键0~9 字母键A~Z 功能键F1~F15 小键盘0~9 Esc键,Tab键,退格键 回车键、空格键、小键盘回车键, 左右Shift键 左右菜单键 左右Alt键 左右Ctrl键 上下左右方向键 Home键,Delete键,Insert键 PageUp键,PageDown键,End键 比如我们要检测左Alt键是否按下,按下的话就做出响应,就可以在上表中找到左Alt键的键码为DIK_LALT,然后就是一句if( ){ }语句: [cpp] view plaincopyprint? 1. if (g_pKeyStateBuffer[DIK_A] & 0x80) fPosX -= 0.005f;

六、DirectInput鼠标按键键值总结

在通常的Windows应用程序中,系统检测鼠标的移动并通过消息处理函数将鼠标的移动作为消息报告给用户,然而这样做的效率非常低下,因为传递给消息处理函数的每个消息首先都要走消息队列这条“官道”,需要慢悠悠地在消息队列中排队,排队完全满足不了我们对游戏即时处理消息的要求。而在Direct3D中,咱们就可以屌丝逆袭走后门了,我们可以直接同鼠标的驱动程序进行交互,而不用走消息队列这条慢悠悠的“官道”。

另外,我们有两种方式来跟踪鼠标的移动为:绝对模式和相对模式。在绝对模式下,鼠标是基于某个固定点的,这个点通常是屏幕左上角,而此时返回的鼠标坐标是鼠标指针所处位置在屏幕坐标系中的坐标。

而另外一种模式,也就是相对模式下,鼠标坐标则是根据上一个已知位置到当前位置所发生的移动量来得到鼠标的坐标值的。在相对模式下得到的鼠标坐标是一个相对位置,而非绝对位置,大家需要注意。

好了,回到正题上来。在DirectInput中,鼠标的移动信息我们通常都是通过一个名叫DIMOUSESTATE结构体来记录的,我们可以在MSDN中查到这个结构体定义如下:

[cpp] view plaincopyprint?

1. typedef struct DIMOUSESTATE { 2. LONG lX; 3. LONG lY; 4. LONG lZ;

5. BYTE rgbButtons[4];

6. } DIMOUSESTATE, *LPDIMOUSESTATE;

这个结构体中,lX,lY,lZ分别记录了X轴,Y轴和Z轴(鼠标滚轮的相对移动量,鼠标没移动的话,他们的值就是0.)。而结构体中的第四个参数rgbButtons[4]记录了四个按钮的状态信息,其中rgbButtons[0]代表鼠标左键,rgbButtons[1]对应鼠标右键。如果需要处理支持更多按钮的鼠标的话,就去用DIMOUSESTATE2结构体吧。 下面我们来看看实例:


VC++2010游戏开发随记之四十二 - 图文(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:船舶管理笔记(1)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: