Direct-X学习笔记--DirectInput

本文介绍了如何使用DirectInput实现游戏控制,以替代Windows消息循环进行更高效的键盘和鼠标输入检测。通过包含DInput.h头文件,引入dinput8.lib和dxguid.lib库,初始化DirectInput设备,设置数据格式,读取设备输入,实现游戏中的实时按键检测。示例代码展示了如何在3D场景中应用DirectInput控制一个茶壶模型进行平移操作。
摘要由CSDN通过智能技术生成

学了绘制简单的2D图形以及3D物体之后,该学学怎么控制物体了!

之前一直是用的是Windows自带的消息循环,WM_KEYDOWN,WM_MOUSELBUTTONDOWN等等,但是这个慢的不行,完全跟不上游戏的速度。以前用GDI/GDI+写游戏的时候使用过一个GetAsyncKeyState方法,可以用于实时的检测键盘按下,虽然简单,不过据本人亲测,会被360发现...所以还是好好学学正统的游戏控制吧...传说中的DIrectInput!


准备工作:

使用DirectInput时,需要包含DInput.h头文件,然后还要引入dinput8.lib以及dxguid.lib库文件。

#include "DInput.h"
//添加库文件
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

创建接口以及设备:

<span style="white-space:pre">	</span>IDirectInput8* m_pDirectInput;					//DirectInput接口对象
<span style="white-space:pre">	</span>//初始化接口对象
	 DirectInput8Create(
		hInstance,					//程序实例的句柄
		DIRECTINPUT_VERSION,		//0x0800当前使用的DirectInput版本号
		IID_IDirectInput8,			//接口标识,使用IID_IDirectInput8即可
		(void**)&m_pDirectInput,	//创建的接口的对象的指针
		NULL						//COM对象相关联参数,为NULL
		);


键盘和鼠标有设定的GUID值(全局唯一ID),其他设备需要通过EnumDevices方法获得GUID值。

初始化鼠标以及键盘设备:

<span style="white-space:pre">	</span>IDirectInputDevice8* m_KeyboardDevice;			//键盘设备接口
	char m_keyBuffer[256];					//用于保存键盘键值的数组

	IDirectInputDevice8* m_MouseDevice;			//鼠标设备接口
	DIMOUSESTATE m_MouseState;				//鼠标键值存储结构体

 
<span style="white-space:pre">	</span>//初始化键盘设备
	 m_pDirectInput->CreateDevice(		//创建设备
		 GUID_SysKeyboard,				//GUID值,对于鼠标和键盘有宏定义,其余设备需要通过枚举找出
		 &m_KeyboardDevice,				//键盘设备指针的指针
		 NULL							//COM相关参数,为NULL
		 );
	 m_KeyboardDevice->SetCooperativeLevel(//设置协作级别
		 hWnd,								//窗口句柄
		 keyboardCoopFlags					//协作级别(前台后台,独占非独占)
		 );
	 m_KeyboardDevice->SetDataFormat(		//设置数据格式
		 &c_dfDIKeyboard);					//键盘鼠标等的数据格式,宏定义
	 m_KeyboardDevice->Acquire();			//获得设备控制权
	 m_KeyboardDevice->Poll();				//轮询设备

	//初始化鼠标设备
	 m_pDirectInput->CreateDevice(GUID_SysMouse, &m_MouseDevice, NULL);
	 m_MouseDevice->SetCooperativeLevel(hWnd, mouseCoopFlags);
	 m_MouseDevice->SetDataFormat(&c_dfDIMouse);
	 m_MouseDevice->Acquire();
	 m_MouseDevice->Poll();
创建之后,需要设置协作级别,通过SetCooperativeLevel协作级别分为前台,后台以及共享,独占模式。具体的参数查阅MSDN。

然后要设置数据格式,通过SetDataFormat设置数据格式。


获得设备输入消息以及读取:

<span style="white-space:pre">	</span>//获得键盘输入消息
	HRESULT hr = m_KeyboardDevice->GetDeviceState(sizeof(m_keyBuffer), (void**)&m_keyBuffer);
	if (hr)
	{
		m_KeyboardDevice->Acquire();
		m_KeyboardDevice->GetDeviceState(sizeof(m_keyBuffer), (void**)&m_keyBuffer);
	}

	//获得鼠标输入信息
	hr = m_MouseDevice->GetDeviceState(sizeof(m_MouseState), (void**)&m_MouseState);
	if (hr)
	{
		m_MouseDevice->Acquire();
		m_MouseDevice->GetDeviceState(sizeof(m_MouseState), (void**)&m_MouseState);
	}

对于按键读取,我们之前定义了一个数组,判断哪一个键被按下了,只需要根据键码对应的索引值读取数组中的值再&0x80即可:

if (m_keyBuffer[DIK_A] & 0x80)//判断A键是否被按下
   return true;
return false;
鼠标的信息为一个结构体,有1X,1Y,1Z,以及rgbButton,分别表示X坐标,Y坐标,滚轮,按键信息。按键信息类似键盘,按照索引值对应不同按键。0为左键,1为右键:

return (m_MouseState.rgbButtons[iButton] & 0x80) != 0;//判断左键是否被按下

return (float) m_MouseState.lX;//返回鼠标X坐标


释放资源:

//释放对象
	if (m_KeyboardDevice)
		m_KeyboardDevice->Unacquire();
	if (m_MouseDevice)
		m_MouseDevice->Unacquire();
	SAFE_RELEASE(m_MouseDevice);
	SAFE_RELEASE(m_KeyboardDevice);
	SAFE_RELEASE(m_pDirectInput);
SAFE_RELEASE定义如下:
#define SAFE_RELEASE(p) {if(p) {(p)->Release(); (p) = NULL;}}


下面是按照浅墨大神的例子,封装的一个DirectInput的类:

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值