学了绘制简单的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
);
初始化鼠标以及键盘设备:
<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;}}