初学Direct X(3)


1.获取外设输入——键盘以及鼠标

无论是获取鼠标还是键盘的设备,首先得初始化DirectInput,不过先把必要的环境先配置好:

所要用到的头文件以及库文件是(相比于前两次):

#include <dinput.h>
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib,"dxguid.lib")

以及要用到的DirectInput对象以及设备(包括键盘和鼠标)对象:

LPDIRECTINPUT8 dinput;
LPDIRECTINPUTDEVICE8A dikeyboard;
LPDIRECTINPUTDEVICE8A dimouse;

准备完毕后开始初始化DirectInput:

HRESULT DirectInput8Create(
HINSTANCE hinst, // 可以通过GetModuleHandle(NULL)
DWORD dwVersion, // DirectInput版本,通常是DIRECTINPUT_VERSION
REFIID riidltf, // 使用的DirectInput版本的引用标识符,我这儿是IID_IDirectInput8
LPVOID * ppvOut, //指向DirectInput对象指针的指针
LPUNKNOWN punkOuter //总是NULL
);

下面是一个调用示例:

HRESULT result = DirectInput8Create(
GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void **)&dinput,
NULL
);

至此,DirectInput的初始化就已经完成

2. 初始化键盘

在初始化了DirectInput之后,可通过调用CreateDevice函数来创建键盘设备

HRESULT CreateDevice(
THIS_ REFGUID,
LPDIRECTINPUTDEVICE8A *lplpDirectInputDevice,
LPUNKNOWN pUnkouter
);

REFGUID:指定要创建的对象类型,例如键盘或者鼠标,键盘是GUID_SysKeyboard,鼠标是GUID_SysMouse

lplpDirectInputDevice:接收DirectInput设备句柄的地址设备指针

pUnkouter : 总是NULL

2.1 设置数据格式

这一步是设置键盘的数据格式,告诉DirectInput如何将数据传给程序,这是一种面对市场上多种多样的输入设备的统一读取办法

HRESULT SetDataFormat(
LPCDIDATAFORMAT lpdf
)

lpdf :不需要我们自己定义,它在dinput中就有定义,对于键盘是 c_dfDIKeyboard,对于鼠标是 c_dfDIMouse

2.2 设置协作级别

这一步是设置协作级别,它按优先级决定DirectInput将键盘输入传递给程序的优先级

HRESULT SetCooperativeLevel(
HWND hwnd,
DWORD
)

dwFlags:最常用的是DISCL_NONEXCLUSIVE | DISCL_FOREGROUND

2.3 获取设备

这一步也是收获的一步,就是使用Acquire获取设备

HRESULT Acquire()

若不在程序结束的时候使用Unacquire()释放设备,则可能会导致DirectInput和键盘句柄处于未知状态,这对于老的Windows来说是不友好的,虽然现代的Windows会自动处理

2.4 获取键盘的输入

通过GetDeviceState来获设备的输入,无论什么输入设备,它都是一个标准

HRESULT GetDeviceState(
DWORD cbData,
LPVOID lpvData
)

对于键盘,需要定义键的数组:

// 对应于cbData,sizeof(keys)
// 对应于lpvData,(LPVOID)&keys
char keys[256];

检查keys数组中的数据方法如下:

if (key[DIK_A] & 0x80){
// do samething
}

2.6 获取键盘输入的完整版

完整的获取键盘输入的程序如下:

bool init_input(HWND  window){
// 初始化DirectInput
HRESULT result = DirectInput8Create(
GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void **)&dinput,
NULL
);
if (result != DI_OK) return false; // 创建DirectInput的keyboard
result = dinput->CreateDevice(GUID_SysKeyboard, &dikeyboard, NULL);
if (result != D3D_OK) return false; // 设置数据格式
result = dikeyboard->SetDataFormat(&c_dfDIKeyboard);
if (result != DI_OK) return false; // 设置协作级别
result = dikeyboard->SetCooperativeLevel(window,DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);
if (result != DI_OK) return false; // 获取设备
result = dikeyboard->Acquire();
if (result != DI_OK) return false; return true;
}
//响应键盘输入
void key_update(){
LRESULT result = dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)(&keys));
if (result != DI_OK) return;
if (keys[DIK_A] & 0x80){
X--;
}
else if (keys[DIK_S] & 0x80){
Y++;
}
else if (keys[DIK_D] & 0x80){
X++;
}
else if (keys[DIK_W] & 0x80){
Y--;
}
}

3. 初始化鼠标

了解了初始化键盘的机制后,初始化鼠标显得就很简单了,在读取鼠标输入前,大都只是传入一个区别于键盘的标识而已,不一样的我会用[异]标注一下

	ZeroMemory(keys, sizeof(keys));
// 初始化DirectInput
HRESULT result = DirectInput8Create(
GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void **)&dinput,
NULL
);
if (result != DI_OK) return false; // 创建DirectInput的mouse对象
result = dinput->CreateDevice(GUID_SysMouse[异], &dimouse, NULL);
if (result != D3D_OK) return false; // 设置数据格式
result = dimouse->SetDataFormat(&c_dfDIMouse[异]);
if (result != DI_OK) return false; // 设置协作级别
result = dimouse->SetCooperativeLevel(window, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
if (result != DI_OK) return false; // 获取设备
result = dimouse->Acquire();
if (result != DI_OK) return false;

3.1 获取鼠标的输入

同样是使用GetDeviceState这个标准的获取函数,但是获取的数据变了,是:

DIMOUSESTATE mouse_state;

也可以使用DIMOUSESTATE2,它能够获取更多的按键

获取函数如下:

result = dimouse->GetDeviceState(sizeof(mouse_state), (LPVOID)&mouse_state);

这里值得注意的是,在DIMOUSESTATE结构中:

typedef struct _DIMOUSESTATE {
LONG lX;
LONG lY;
LONG lZ;
BYTE rgbButtons[4];
}

lXlYlZ都只是相对于上一帧鼠标的相对移动坐标,在rgbButtons

rgbButtons[0]是鼠标左单击,

rgbButtons[1]是鼠标左单击,

rgbButtons[2]是鼠标滑轮按下

判断获取输入的代码如下:

if(mouse_state.rgbButtons[0] & 0x80)
{
//do samething
}

初学Direct X(3)的更多相关文章

  1. 初学Direct X(7) ——位图的旋转,缩放以及平移

    初学Direct X(7) --位图的旋转,缩放以及平移 本文旨在实现通过D3DXMatrixTransformation2D函数实现位图的旋转,缩放以及平移操作,但是具体的原理部分会在后面进一步的探 ...

  2. 初学Direct X(10)—— D3D基础预备知识

    初学Direct X(10) -- D3D基础预备知识 1. 像素格式 D3DFMT_X8R8G8B8(F) X:未加使用 8:8位用于显示 B:用于显示蓝色 F:浮点像素类型 以下三个较为常用,使用 ...

  3. 初学Direct X(9) ——文字的显示

    初学Direct X(9) --文字的显示 本次学习如何使用ID3DXFont创建字体,使得我们可以在任何安装了Windows系统中TrueType字体来打印文字,不过最好使用标准字体,这样文字在每一 ...

  4. 初学Direct X(8) ——碰撞检测

    初学Direct X(8) --碰撞检测 真正让一个游戏鹤立鸡群的是程序对碰撞的响应有多好,这里介绍两种检测的方法: 1) 基于边框的碰撞检测 2) 基于距离的碰撞检测 1. 基于边框的碰撞检测 1. ...

  5. 初学Direct X(6)

    初学Direct X(6) 这一文本应和上一篇放在一起的,但是上一章写着写着发现对Draw绘制透明位图的方式有感觉了,决定就单写一篇,留作笔记了. 那这一篇是记录如何使用位图表来绘制动画帧,想象一下, ...

  6. 初学Direct X(5)

    初学Direct X(5) 前面学习了使用表面绘制屏幕,但这种方法与另一种比较起来,有着绘图速度颇慢以及缺乏对任何透明类型的支持,这就是前面的篮框以及炸弹会有黑色背景的原因,这种方法就是纹理.他可以绘 ...

  7. 初学Direct X(4)

    初学Direct X(4) 本文学着做出一个如下的小游戏 游戏方式是使用键盘控制红色的Bucket收集蓝色的炸弹 1.酝酿一下 现在我已经掌握: 将位图文件加载到内存 绘制位图到buckbuffer ...

  8. 初学Direct X (2)

    初学Direct X (2) 这一次要学习如何现实位图,尽管看过对双缓冲机制还有很多疑问,但是这并不阻碍我对他的入门了解 Direct3D提供了一个双重/后台缓冲区,在调用CreateDevice之时 ...

  9. 初学DirectX(1)

    初学Direct X (1) Direct3D设备用于访问视频卡的帧缓冲区,以及后台缓冲区.由于IDE是vs2013,默认安装了direct 9,只需要在使用头文件(1)并像使用库文件(2)即可 #i ...

随机推荐

  1. python之self

    python中的self与Java中的this类似,类的函数通过self引用从而实现对类的数据类型进行访问操作. 1. self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数.(类的方法与 ...

  2. 【UVA11806 Cheerleaders】 题解

    题目链接:https://www.luogu.org/problemnew/show/UVA11806 容斥原理+组合数 正着找合♂fa的不好找,那就用总方案数-不合♂fa的 #include < ...

  3. 使用Scanner将InputStream类型转换成String

    我们在测试项目中经常会遇到这样的情形: 1. 从文件或网络得到一个InputStream,需要转换成String赋值到别的变量做为另一个方法的入参. 2. 从文件或网络得到一个InputStream后 ...

  4. http1.X与2.0

    HTTP HTTP 1.X HTTP是建立在TCP协议上的,HTTP协议的瓶颈及优化都是基于TCP协议本身的特性. TCP建立连接时有三次握手 会有1.5RTT的延迟,为了避免每次请求都经历握手待来的 ...

  5. 史上最简单的SpringCloud教程 | 第十三篇: 断路器聚合监控(Hystrix Turbine)(Finchley版本)

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2018/08/30/sc-f13-turbine/ 本文出自方志朋的博客 上一篇文章讲述 ...

  6. 【Django笔记三】Django2.0配置mysql模型

    一.环境版本信息: 操作系统:windows10 Django版本:2.0.5 Python版本:3.6.4 Mysql版本: 5.5.53   安装mysql 二.安装Mysqlclient: 1. ...

  7. 什么是 better-scroll(转自知乎网 : 黄轶)

    什么是 better-scroll better-scroll 是一个移动端滚动的解决方案,它是基于 iscroll 的重写,它和 iscroll 的主要区别在这里.better-scroll 也很强 ...

  8. Qt 项目主进程接收Alarm 后在GUI上显示,并且可以有选择性输出文件

    项目主进程接收报警后,将alarm msg 发送给代理, 并将其分发: else if (msg.name == "MesLCUalarmRep") { QString error ...

  9. chromium之message_pump_default

    看看头文件,默认的消息泵,该类实现了MessagePump的四个接口 class MessagePumpDefault : public MessagePump { public: MessagePu ...

  10. MySQL正则表达式的问题

    原本以为 正则表达式里面的特殊\d匹配数字放到sql语句里面也是适用的,没想到一直不匹配.但是放到编程语言java或者js里面又匹配.看了一下原来sql对正则的支持没有那么全面.一定要用[0-9]代表 ...