DirectInput编程基础 - 简介

导读:
  DirectInput编程基础 - 简介 出 处: 中国游戏开发者
  [ 2001-09-09] 作 者
   目 录
  1.1 DirectInput概念
  1.2 设置DirectInput
  1.3 列举设备
  1.4 设置设备
  1.5 取得输入数据
   绪言
  输入相对于图形和声音而言从未成为游戏开发中的非常重要的论题。读取键盘按键、鼠标移动和游戏杆位置似乎并没有什么困难,但随着新输入设备对市场的强烈冲击以及DirectX的发行,这一问题变得日益重要了。
  如果用户是DirectInput编程的新手,那么应先排除掉一些旧观念。应记住的重要一点是DirectInput的得名是因为它直接与设备驱动器通讯,对鼠标和键盘也就意味着立即响应硬件中断,而不是等待Windows发送消息证明已发生输入事件。当然,DirectInput放弃了Windows的消息队列,在虚构WM_KEYDOWN或WM_MOVSEMOVE等消息的同时也就不再享受Windows提供的一些服务。这种服务大都不是对游戏输入特别有用, 但它有助于理解缺少这些服务时所产生输入信息的含义,后面有关鼠标和键盘输入的章节中,将深入地讨论这一问题。
  当然,DirectInput放弃了Windows的消息队列,在虚构WM_KEYDOWN及WM_MOVSEMOVE等消息的同时也就不再享受Windows提供的一些服务。这种服务大都不是对游戏输入特别有用,但它有助于理解缺少这些服务时所产生输入信息的含义,后面有关鼠标和键盘输入的章节中,将深入地讨论这一问题。
   1.1、DirectInput概念
  下面看一下DirectInput所关心的内容:输入设备及其部件。
   1.1.1 设备
  DirectInput可识别三种基本设备类型:
  键盘,标准系统键盘。
  鼠标,这一类中包括所有类似于鼠标的设备,如触摸板、跟踪球以及相应的按键。
  游戏杆,相对于其它类型的控制器和力反馈设备而言,这是易于产生误解的名称,其范围从简单的游戏杆直至虚拟现实的复杂设备。本书中,我们使用这一名称是为了与DirectInput术语保持一致,但应记住,当谈到“游戏杆”时,这一说法一般是“特殊游戏控制器”的简称。   只要讲到DirectInput,那么设备就是指由设备驱动器代表的螺丝、螺母集合, 带有内置跟踪球或触摸板的膝上键盘算作两个设备, 但带有力反馈激励器的游戏杆却是一个设备。DirectInput API和文档中把返回数据或产生力反馈效果的设备的不同部分都称为设备对象实例或简称对象,这两种叫法都不是最佳的。因为“对象”一词(在其它情况下)指代码对象,“实例”批COM接口的例示。在本文中,我们尽量避免使用这种叫法,而用更准确的“设备物”取代。我们认为,设备物可以是任何的键、按钮、视点帽或轴等。
  另一个更易混淆的问题是“设备”可以指物理对象(如其驱动器)也可以指DirectInput创建的DirectInputDevice对象。当讲到创建一个设备时,我们指获得一个指向IDirectInputDevice接口的指针,以便可以用相应方法与设备驱动器通讯。
   1.1.2 按钮和轴
  按钮是任何具有开和关状态的设备。DirectInput在概念上不对按钮加以区分,它们可以位于鼠标上、游戏杆上或游戏板上,还可以是键盘上的键。
  轴是设备中的一种控制而不是按钮 — 有位置而不是开、关状态的事物。严格地说,轴不是物理对象,而是由物理对象向某一方向的移动产生的一个值。游戏杆、跟踪球、鼠标球和触摸板等一个物理对象控制两个轴的值,分别称为X轴和Y轴,因为它们一般控制的是二维计算机屏幕上的指针或游戏元素。游戏杆上的减速把手或滑块只控制一个轴,它与MicrosoftIntelliMouse鼠标中的转轮是一样的。游戏杆上也可能有其它的轴,如用于控制舵方向的扭转动作等,用于驾驶、飞行摸拟等的特殊控制器依靠操纵轮、轭、踏板等操纵多个轴。
  视点帽是例外的一种情况,它不是有任何按钮或轴,后面有关游戏杆的章节中将详细讨论这一设备。应记住的重要一点是,轴与物理空间或其它事件之间不存在固定关系。
  程序上下文中设备的Z轴(尽管与三维坐标系统中一个轴的名称相同)可能与空间的第三维毫无关系, 而其作用却可能是控制翻页、音量或其它非空间属性。虽然已有一些成形的约定,如把X 轴与控制器的左右运动和屏幕上的水平方向相关联,但映射设备中的物理量与DirectInput中逻辑轴的关系是由设备驱动器实现的,而把这些轴与它们发挥作用的游戏概念关联起来是由程序设计者完成的 — 或给使用者以选择的机会并由他们完成。
  轴可以是绝对的或相对的。游戏杆中的X轴和Y轴天生是绝对的,因为在任何方向它们都只能移动有限的距离,他们的位置也通常是以与某一固定中心点的距离而测量的。相反,鼠标天生是一种相对的设备,因为它可以在任何方向上无限地移动,而且也设有“原点”,对它所关心的只是在上一次检测之后它沿每个轴运行的距离。
  DirectInput可以违反天性而把任何轴当作绝对的或相对的来处理。但多数情况下把鼠标(包括转轮)处理为绝对的轴,把其它设备 — 杆、滑块、拨号盘当作相对轴处理,也就是说,对鼠标要考虑的是其运动,而其它轴考虑的则是位置。
   1.2、设置DirectInput
  简单地调用DirectInputCreate函数(见表1-1)就可以初始化DirectInput系统,此函数将返回一个指向IDirectInput接口的指针, 然后可以用此接口的方法列举设备并创建设备对象,这些设备对象是DirectInput的工作部分。
   表1-1 DirectInputCreate函数
  HRESULT WINAPI DirectInputCreate(
  HINSTANCE hinst,
  DWORD dwVersion,
  LPDIRECTINPUT * lplpDirectInput,
  LPUNKNOWN punkOuter
  );
   参数 说明
  HINSTANCE hinst 创建DirectInput对象的程序或DLL的实例句柄
  DWORD dwVersin 设计程序所用的DirectInput版本号,此值通常为DIRECTINPUT_VERSION,但看到的是文本
  LPDIRECTINPUT *lplpDirectInput 新DirectInput对象的指针地址
  LPUNKNOWN pUnkOuter 必须为NULL
   注意:DirectX非常灵活地允许用户用以前的版本(实际即为版本3)进行设计,只要给DirectInputCreate函数传递一个非DIRECTINPUT_VERSION值就行了。如果传递的是OXO300,则程序在装有DirectX 3运行文件的系统中会很好地运行。但必须确保在所用结构与DirectX与定义的不同时,使用与DirectX3兼容的结构,如DIDEVCAPS_DX3。
  简单有效的方法是在包含DINPUT.H文件前给出自己对DIRECTINPUT_VERSION的定义,如:现在不用担心使用旧结构了,因为DINPUT.H被解释过以后,所存的新结构都奇迹般地转换成对应的早期结构,其中DIDEVCAPS与DIDEVCAPS_DX3一致,如此类推。
   提示:即使是用新版DirectInput进行设计,也可以使用旧版本中的结构, 用途之一是IDirectInputDevice:: GetCapabilities方法,通过传递传来DIDEVCAPS_DX3结构将省去DirectInput查询力反馈驱动器的一步, 可使速度略有提高。当然只有在对力反馈不感兴趣时才可这样做,同时不要忘记初始化dwSize成员为sizeof(DIDEVCAPS_DX3)。
   1.3、列举设备
  你一般不需要列举鼠标和键盘。即使与用户系统连接的这两种设备都不止一个(当然这种可能很小),我们也可以通过在IDirectInput::CreateDevice中使用预定义的变量GUID_SYSMOUSE 和GUID_SYSKEYBOARD来解决。
  游戏杆则属于另一种情况,因为不存在所谓的“系统游戏杆”。一些用户会安装多种游戏控制器的驱动程序,甚至把多个这种设备连接到系统。至少,为了获得了一个合适的设备或多个设备的GUID,要对其进行列举,或许为了使用户能进行选择还需要列举所有可用的设备。后面有关游戏杆的章节中将详细讨论这一问题。
  要列举设备需要先建立一个回调函数,然后调用EnumDevices方法,见表1-2。
   表1-2 EnumDevices方法
  HRESULT IDirectInput::EnumDevices(
  DWORD dwDevType,
  LPDIENUMCALLBACK lpCallback,
  LPVOID pvRef,
  DWORD dwFlags
  );
   参数 说明
  DWORD dwDevType DIDEVTYPE_* 值,指定要查找的设备类型,如为0则查找所有类型
  LPDIENUMCALLBACK lpCallback 回调函数地址
  LPVOID pvRef 可为任何值,典型值为一指向数据的指针,可在回调函数中使用或修改。这是传给回调函数的第二个参数
  DWORD dwFlags 对列举的更严格的限制标志。可以为(a)DIEDFL_ALLDEVICES(=0)或(b)DIEDFL_ATTACHEDONLY和DIEDFL_FORCEFEEDBACK之一或两者皆有
  EnumDevices用到的回调函数可以有许多用途。被列举的特定设备的许多信息都在DIDVICEINSTANCE结构中,此结构由DirectInput自动建立并传给回调函数,下面是回调函数如何使用这些信息的几个例子:
  1)创建此设备。此设备的实例GUID已位于DIDEVICEINSTANCE结构中,因此回调函数可以很方便地获取IDirectInputDevice接口并进行其它初始化工作。
  2)检查设备的子类型,例如, 可以检查键盘子类型并对游戏功能对应的键做必要的修改(但是,如果列举键盘没有别的重要目的,则可以通过调用IDirectInputDevice::GetDeviceInfo简单地实现)。下面的例子说明了如何在回调函数中更改对键功能的分配。这里假定调用EnumDevices时已限定了列举的是键盘。
  BOOL CALLBACK DIEnumKbdProc( LPCDIDEVICEINSTANCE lpddi,
  LPVOID pvRef )
  {
  switch ( GET_DIDEVICE_SUBTYPE( GET_DID
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值