DirectInput开发包【转载】

来源:互联网 发布:钢琴作曲软件 编辑:程序博客网 时间:2024/06/06 19:45
 在前面的一些程序中对于控制用的都是windows的消息机制来实现的,这样做是可以,但是感觉有点怪怪的,按'W'前进时,开时会有一点的延时。

        Windows控制机制有几个缺点:效率低;Win32API对游戏杆的支持并不理想;鼠标被限制在3键、滚轮、二维移动;在Win32模式下,键盘接口完成了重复按键,虚拟键码转换成ACSII字符的操作,但游戏并不需要这些多余的转换;当连续完成多个操作,消息队列排满的时候,渲染过程将会被堵塞,操作得到的反应会延迟等。Windows消息机制是键盘或鼠标硬件中断传给CPU,再经CPU处理传给系统消息队列,接着由系统扔给程序消息队列,这样感觉就拢了一个大圈了。相对来说用DirectInput就好多了,它是直接侦测键盘或鼠标的硬件中断,返回键值(对于键盘来说用GetAsyncKeyState()方法也是直接侦测硬件中断的,本人喜欢用这个,简单,呵呵,但这里讲DirectInput开发包就不多谈这个了)。

       在使用DircetInput时,需要dinput.h头文件和dxguid.lib,dinput8.lib二个lib。

       DirectInput的组成:使用IDirectInputDevice8接口。IDirectInput8,用来初始化输入系统和创建输入设备对象。IDirectInputDevice8用来表示输入设备的COM对象。IDirectInputEffect实现反馈效果。DirectInput适用于键盘、鼠标和游戏杆,目前几乎所有的输入设备都提供了DirectInput驱动程序。

DirectInput在游戏中的生命周期:
(1)创建DirectInput对象;
(2)枚举相关类型的设备;
(3)创建IDirectInputDevice8对象;
(4)设置设备的协调层级,设置数据格式,设置设备参数;
(5)获取设备;
(6)读取设备数据,设备丢失时重新获取设备;
(7)关闭DirectInput,释放输入设备,DirectInput对象,动态数据。

DirectInput实现键盘控制

1.初始化键盘对象
1)创建DirectInput对象
//创建DirectInput8对象
LPDIRECTINPUT8   m_pDInput;
if(DI_OK!=DirectInput8Create( hInst,DIRECTINPUT_VERSION,
     IID_IDirectInput8,(LPVOID*)&m_pDInput,NULL))
 MessageBox(hWnd,"创建DInput 对象失败!","ERROR",MB_OK);

2)创建设备对象
LPDIRECTINPUTDEVICE8 m_pKeyboard;
//创建键盘设备
if(DI_OK!=m_pDInput->CreateDevice(GUID_SysKeyboard,     
          & m_pKeyboard,NULL))
 MessageBox(hWnd,"创建键盘设备失败!","ERROR",MB_ICONERROR|MB_OK);
2 设置数据格式

//设置数据格式  
if(DI_OK!=m_pKeyboard ->SetDataFormat(&c_dfDIKeyboard))
 MessageBox(hWnd,"设置键盘数据格式失败!","ERROR",MB_OK);
3 设置键盘协调层级
m_pKeyboard->SetCooperativeLevel(hWnd,DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);


4 取得键盘控制权
在读取键盘输入的数据之前,必须先让应用程序获取设备的控制权。

HRESULT Acquire(VOID);

当设备控制权失去后,读取设备数据时会返回DIERR_INPUTLOST错误,如果要重新获取控制权,可以在窗口激活消息响应过程中重新获取设备:

case WM_ACTIVATE:
 if( WM_INACTIVE != wParam && m_pKeyboard )
 {
  // 窗口激活后获取设备控制权.
  m_pKeyboard->Acquire();
 }
    break;

5 读取键盘数据
每种设备都可以使用立即数据与缓冲数据,而二者的数据获取、表示和存储方式也不尽相同。
键盘立即数据
char m_strKeyState[256];
if(DI_OK!= m_pKeyboard->GetDeviceState(sizeof(m_strKeyState), (LPVOID)
           &m_strKeyState))
 MessageBox(NULL,"Failed to GetDeviceState","ERROR",MB_OK);
if(m_strKeyState[DIK_A] & 0x80)
 vectKB.x-=5;
扫描键码和Windows API中的虚拟键码是不同的,虚拟键码是由扫描码转换而来的。扫描码不同的兼容键盘,DirectInput会把它们转换成物理键码。

鼠标数据的获取和键盘是类似的
1.初始化
//创建DirectInput8对象
if(DI_OK!=DirectInput8Create( hInst,DIRECTINPUT_VERSION,    IID_IDirectInput8,(LPVOID*)&m_pDInput,NULL))
 MessageBox(hWnd,"创建DirectInput 对象失败!","ERROR",      MB_ICONERROR|MB_OK);
//创建鼠标设备
if(DI_OK!=m_pDInput->CreateDevice(GUID_SysMouse,&m_pDInputMouse,NULL))
 MessageBox(hWnd,"创建鼠标设备失败!","ERROR",MB_ICONERROR|MB_OK);
2 设置数据格式
3 设置鼠标协调层级
4 获取鼠标控制权
5 获取鼠标数据
使用鼠标的坐标系统
默认情况下,鼠标的移动量是相对位移,单位是硬件移动的点数(dps)。鼠标没有坐标,鼠标移动量不受光标影响,和屏幕分辨率没有关系。鼠标是相对设备,移动并没有范围。

 坐标轴   +       -     X右方  左方 Y 上方 下方 Z(滚轮) 背向玩家转动 向玩家转动
使用相对位移时,
立即数据:返回的是自上次读取鼠标数据后到这次读取鼠标数据之间发生的位移
缓冲数据:返回的是上次读取缓冲区后鼠标的移动量。

原创粉丝点击