2017.08.25
今天学习一下DX从键盘和鼠标获得输入
这里需要添加头文件和库
#include<dinput.h>
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib, "dxguid.lib")
首先是键盘输入(扫描键盘来看是否有输入)
需要两个全局变量,一个是程序所要用的主DirectInput对象,另一个是输入设备对象
LPDIRECTINPUT8 dinput; //主DirectInput对象
LPDIRECTINPUTDEVICE8 dinputKeyBoard; //设备对象
然后调用DirectInput8Create来初始化DirectInput:
HRESULT WINAPI DirectInput8Create(
HINSTANCE hinst
DWORD dwVersion
REFIID riidltf,
LPVOID *ppvOut,
LPUNKNOWN punkOuter
);
//使用
hResult = DirectInput8Create(
GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void**)&dinput,
NULL
);
创建我们传递给他的主DirectInput对象,
GetModuleHandle(NULL) 函数获得当前程序的实例句柄
初始化对象后调用CreateDevice来使用这个对象创建新的DirectInput设备
HRESULT CreateDevice(
REFGUID rguid,
LPDIRECTINPUTDEVICE *lplpdirID,
LPUNKNOWN pUnkouter);
第一个参数值是制定创建类型,键盘或鼠标或其他啥的:
GUID_SysKeyBoard :键盘 GUID_SysMouse 鼠标
第二个参数是接受DirectInput设备句柄的地址的设备指针,调用并创建键盘设备:
hResult = dinput->CreateDevice(GUID_SysKeyboard, &dinputKeyBoard, NULL);
接着初始化键盘,初始化键盘句柄,为输入做准备,先设置数据格式,告诉DirectInput如何将数据传回给程序
hResult = dinputKeyBoard->SetDataFormat(&c_dfDIKeyboard);
这个函数的参数是设备类型,c_dfDIKeyboard代表键盘,c_dfDIMouse 是鼠标
然后设置协作级别(不是很懂这里,大概是优先级之类的)
hResult = dinputKeyBoard->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
最后初始化设备
hResult = dinputKeyBoard->Acquire();
Acquire获得键盘设备,不过要在游戏结束前还回去:
dinputKeyBoard->Unacquire();
然后就可以轮询读取键盘按键了,我们需要在游戏循环的某个地方轮询键盘来更新键值,所以需要先定义一个键的数组,然后轮询键盘来填充这个数组:
char keys[256];
dinputKeyBoard->GetDeviceState(sizeof(keys), (LPVOID)&keys); //轮询获得键值
if (keys[DIK_SPACE] & 0X80)
{
//按下空格的操作
}
键盘目前就是这样,不过个人感觉这样轮询还是效率比较低的,可能不如Windows异步GetAsyncKeyState效率高吧(这里不确定,不是很了解)
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
异步的键盘按下判断
接下来是鼠标
和键盘类似,在初始化或者说获得了DiretInput后便可以继续获得鼠标对象,因为鼠标和键盘共享DirectInput对象和设备指针。
创建和初始化鼠标设备,和键盘类似,还有就是在结束前还回鼠标Unacquire():
//创建鼠标设备
hResult = dinput->CreateDevice(GUID_SysMouse, &dinputMouse, NULL);
//设置数据格式
hResult = dinputMouse->SetDataFormat(&c_dfDIMouse);
//设置协作级别
hResult = dinputMouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
//获取鼠标
hResult = dinputMouse->Acquire();
轮询鼠标,看移动或者按键:
//轮询鼠标
DIMOUSESTATE mouse_state;
dinputMouse->GetDeviceState(sizeof(mouse_state), (LPVOID)&mouse_state);
//判断某个按键(0~3)是否被按下
byte bt0 = mouse_state.rgbButtons[0] & 0x80;
这个DIMOUSESTATE :
typedef struct DIMOUSESTATE {
LONG lx;
Long lY;
Long lZ;
BYTE rgbButton[4];
}DIMOUSESTATE;
鼠标状态的结构。