首页 | 互联网 | IT动态 | 网络设备 | 服务器 | IDC | 安全 | Cisco | Windows | Linux | Java | .Net | Oracle | CIW | 华为 | 专题
IT技术 | 网页设计 | 平面设计 | 电子书下载 | 教学视频 | 方案 | 数字网校 | 直播室 | 虚拟考场 | 面授培训 | 搜索 | 博客 | 沙龙 | 论坛
 您现在的位置: 中国IT实验室 >> 游戏开发 >> 游戏策划 >> 文章正文
游戏中输入的处理
来源:中国IT实验室收集整理 作者:佚名 时间:2007-9-30

 键盘概述:
   当我们在键盘上按下一个键时,字符就神奇的出现在了屏幕上.键盘跟系统之间的交互是非常烦琐的,但作为游戏程序员的我们必须理解这里面的奥秘,为以后的开发扫平障碍.
   当我们按下或者是释放一个键时,一个信号将被传送给键盘的微处理器,随后键盘微处理器将向计算机系统"申请"一个中断,同时系统从键盘那里获得了一个字符码,从而使得系统得知到底是那个键被按下或者释放,微处理器给计算机系统传送的那个字符码被称作扫描码.下图让我们有个更为清晰的理解:

 这里需要指出的是一个扫描码的大小是一个字节,其中低7位(即bit0-6)表示哪个键被操作,而最高位代表是被按下还是被释放.所以我们所能处理的最多的键的数目是128.
Windows中的键盘处理:
   想在windows平台上混碗饭吃的人如果不懂消息机制的话那将很难,正是windows的消息机制使得对于键盘的处理变的简单.首先windows把扫描码转换为虚拟码和ASCII码,然后通过消息机制来告诉程序员某个键被按下了.虚拟码只是将原来的扫描码在windows里进行了包装,用VK_A而不是30来表示A.而ASCII码是为了实现扫描码和字符之间的对应关系的,在ASCII码里面,A 和 a所对应的ASCII码是不同的,最多表示128种不同的字符.为了能表示更多的字符,有时候要用到扩展的ASCII码,所谓扩展就是增添了一位附加信息,这样就使得可以表示的字符数目达到了256个,但是仍然不能达到要求,这也是Unicode产生的原因之一.到了Unicode每个字符用16个比特位来表示,所以总共能表示65535种字符,满足了目前所有需求.
   对于接收到的虚拟码或者ASCII码如何处理就取决于程序员了,如果我们想用来做文字处理,那么我们就把字符插入到编辑区域.对于游戏来说大多是控制游戏中的各种角色的.
windows中鼠标的处理:
    鼠标相对于键盘来说就更加简单了,因为鼠标上的"零件"实在是太少了.当我们按下一个键时就给系统发送一个信号,释放时同样要向系统发送信号.鼠标每隔一个很小的时间间隔就想系统报告它的移动信息等,鼠标的驱动程序读入这些数据然后转换成相应的形式.然而用传统的消息机制来处理鼠标消息是很慢的,有时候不能满足游戏的需要,因为每个鼠标消息都要传送给消息处理过程,然后再被插入到相应的消息队列等待处理,这对于游戏的实时性来说是很不利的,玩家可不想在自己发出命令后要过一段时间才有反应,要的是速度!
 
   从上面的表述我们发现,传统的windows输入处理都要先由设备驱动程序处理,然后再交给系统处理,最后才再给相应的应用程序.为什么不绕开系统而让设备驱动程序跟应用程序直接交互呢?这就是DirectInput的原理.
  
DirectInput基础:
   DirectInput用一组COM对象来表示输入系统和具体的输入设备.最主要的对象 IDirectInput8,用来初始化输入系统和创建输入设备对象.
DirectInput COM 对象
IDirectInput8           最中要的DirectInput COM对象,其他所有的对象都要通过它来创建.
IDirectInputDevice8     用来表示输入设备的COM对象,每种输入设备都与之对应的COM设备对象.
IDirectInputEffect      用来实现反馈效果的COM对象.

      所有的输入设备都使用同一个接口对象来处理:IDirectInputDevice8.每种设备都以此为基础再加上各自的特有信息.下图可以帮我们理解:


IDirectInput8创建各种IDirectInputDevice8,然后由IDirectInputDevice8来创建IDirectInputEffect对象.

IDirectInput8组件对象包含一组函数用来初始化数据系统,获得输入设备接口.用的最多的是以下两个函数:
IDirectInput8::EnumDevices()  和 IDirectInput8::CreateDevice().在以后的学习中我们会详细的介绍这两个函数.
DirectInput的初始化:
   为了使用DirectInput,我们首先要在程序文件中包含"DInput.h",并且连接DInput8.lib.IDirectInput8对象代表了整个输入系统,所以它是最重要的,看下面的代码:
IDirectInput8 g_pDI; // 声明全局的IDirectInput8对象
DirectInplut为我们提供了DirectInput8Create()帮助器函数,下面是它的原型:

HRESULT WINAPI DirectInput8Create(
HINSTANCE hInstance, // 应用程序实例
DWORD dwVersion, // DIRECTINPUT_VERSION
REFIID riidltf, // IID_IDirectInput8
LPVOID *ppvOut, // 要创建对象的指针
LPUNKNOWN pUnkOuter); // set to NULL

这个函数中的大多数参数取默认值即可,我们只需要提供所要创建对象的指针即可.
下面我们来看一个完整的创建对象的例子:
IDirectInput8 *g_pDI; // global DirectInput object
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, \
LPSTR szCmdLine, int nCmdShow)
{
    HRESULT hr;
    hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, \
              IID_IDirectInput8, (void**)&g_pDI, NULL);
     // return failure if an error occurred
    if(FAILED(hr))
       return FALSE;
    // Go on with program here
初始化输入系统就这么几句代码搞定了,下面我们就来创建具体的输入设备.
输入设备的创建:
    很高兴我们又一次地站在了巨人的肩膀上,微软在简化输入系统方面做了很多工作,这就使得我们学习起来很轻松.我们可以使用同一个COM对象来处理系统中所有的输入设备.各种输入设备的创建和使用是极为类似的,我们首先给出创建和使用它们的步骤,见下表:
创建和使用输入设备的步骤:
步骤                                                      使用到的接口函数
Obtain a device GUID                          IDirectInput8::EnumDevices
Create the device COM object            IDirectInput8::CreateDevice
Set the data format                               IDirectInputDevice8::SetDataFormat
Set the cooperative level                     IDirectInputDevice8::SetCooperativeLevel
Set any special properties                   IDirectInputDevice8::SetProperty
Acquire the device                               IDirectInputDevice8::Acquire
Poll the device                                      IDirectInputDevice8::Poll
Read in data                                          IDirectInputDevice8::GetDeviceState

别忘记了首先要声明一个设备对象指针:
IDirectInputDevice8 *pDIDevice;
下面我们来逐一说明每个步骤:
获得唯一设备号:
    系统中的每个输入设备都有一个GUID(全局唯一标识),要想使用输入设备,我们就必须先得到它的GUID.对于键盘和鼠标来说这个工作是很简单的,因为DirectInput分别为它们定义了GUID_SysKeyboard和GUID_SysMouse.但是对于其它的输入设备,我们必须通过枚举来获得它们的GUID:
HRESULT IDirectInput8::EnumDevices(
DWORD dwDevType, //所要枚举的设备类型
LPDIENUMCALLBACK lpCallback, //每当找到一个该类型的设备时将自动调用该函数
LPVOID pvRef, // 可以把它当成上面回调函数的参数
DWORD dwFlags); // 标志位
下面是dwFlags的取值:

  DIEDFL_ALLDEVICES
All installed devices are enumerated. This is the default behavior.

[1] [2] 下一页  

【责编:Luzi】

中国IT教育热线咨询

相关文章
游戏设计时需要问自己的三问题
浅谈游戏企划-新手入门篇
暴雪称霸游戏业界的六大秘密绝招
游戏中打怪行为的人类学分析
独家专访网易游戏策划是怎样炼成的
推荐文章
中国IT教育热线咨询

 精彩友情推荐
·神州数码交换机
·神州数码交换机价格
·神州数码网络交换机
·netgear交换机
·网件交换机
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
 基础入门  开发文档
 最新推荐
  多数的Windows程序都需要Windows.h和Windowsx.h这两个头文件,要确保使用它们。当然,你还需要其它......
游戏引擎演化史
在Windows上安装OGRE的方法
关于滤镜遮罩概念,Sobel 遮罩
游戏开发新手入门之Windows编程
游戏开发新手入门之位图化图形
教你实现卡通渲染的另类勾边方法
游戏设计大师谈如何成为一名游戏设
Visual C#编写 3D游戏框架示例
真正的 Java 学习从入门到精通
游戏开发经验——游戏开发的基本常
  针对于移动新出台的政策,需要尽快地把我们公司的游戏对应到不同的手机平台,这是针对市场策略的有利调整............
载入位图文件到DirectDraw
Archer Game Suite 是什么?
浅谈游戏企划-新手入门篇
暴雪称霸游戏业界的六大秘密绝招
骨骼动画及示例Skinned Mesh的解析
游戏五要素模型假设
Quake-III代码里神奇的浮点开方函数
基于Dialogue的MFC程序调用DirectX
关于Kjava手机平台移植可行性报告
网络游戏的数据传输处理和防火墙穿
  培训中心