热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第二章第五节统一输入接口

统一输入接口目前我们已经会怎样和输入硬件通信的基本方法(Nowthatwehavethebasicsdownonhowtocommunicatewiththeinputha

统一输入接口

目前我们已经会怎样和输入硬件通信的基本方法(Now that we have the basics down on how to communicate with the input hardware),是时候把这些信息整合进游戏引擎了。游戏引擎只有一个类,封装了三种输入设备,并为游戏提供了一个统一的接口。这个类,我们把它叫做GameInput,从IDisposable接口继承而来。此接口定义了一个Dispose方法,提供清除函数,在C++里一般是析构函数。此类的构造函数会创建所有的输入设备,并只接受一个参数,即前面提到过的应用程序的窗口句柄。

 

虽然我们可以强加让游戏在游戏循环里查询GameInput来取得击键,但是有更好的方式:我们可以使用action映射。Action映射把一个键盘的键或者鼠标的按钮与一个指定的函数相关联。在每帧里有键或者按钮被按下(或者按下的状态被改变)则调用特定的函数。这让输入系统基于事件而不是基于查询,这会提供效率。DirectInput有内建的action映射功能。我们这个游戏引擎实现了分离的action映射系统,目的是示范action映射究竟是如何工作的。一旦你理解了其中的思想,只要你喜欢你可以直接使用微软内置的版本。

 

Action映射里的每一个实体包含mapping结构或者axis mapping结构的实例,如列表2-2所示:

列表:Mapping结构

struct Mapping

{

   public int key;

   public ButtonAction action;

   public bool bOnTransition;

}

struct AxisMapping

{

   public int key;

   public AxisAction action;

}

结构中的key是索引,是键盘状态数据或者鼠标按钮数据,指示了控制action映射到什么上。开头的256个值表示键盘实体,接下来的8个是表示鼠标按钮,最后的32个是表示操纵杆按钮。ButtonAction委托(delegate)表示一个不需要参数也没有返回值的函数。此函数通常用来在游戏中执行一些动作,例如移动主角,开火或者游戏开发者想做的其他动作。AxisAction委托(delegate)使用这个数据为此轴每一帧都被调用。两个委托的定义如下:

public delegate void ButtonAction();

public delegate void AxisAction(int nCount);

GameInput的公开方法如列表2-3所示。我将在随后的几页里为这些方法提供简短的说明。如果你对实现的细节有兴趣,请参考GameInput.cs 源文件(源代码的一部分,可以从Apress Web网站下载 http://www.apress.com

列表2.3GameInput方法列表

GameInput(System.Windows.Forms.Form form)

void Poll()

bool IsMouseButtonDown( int nButton )

bool IsKeyPressed()

bool IsKeyPressed(Key key)

void MapKeyboardAction( Key key, ButtonAction proc, bool bTransition )

void MapMouseButtonAction( int nButton, ButtonAction proc, bool bTransition )

void MapJoystickButtonAction( int nButton, ButtonAction proc, bool bTransition )

void MapMouseAxisAction( int nAxis, AxisAction proc )

void MapJoystickAxisAction( int nAxis, AxisAction proc )

void UnMapKeyboardAction( Key key )

void UnMapMouseButtonAction( int nButton )

void UnMapJoystickButtonAction( int nButton )

void UnMapMouseAxisAction( int nAxis )

void UnMapJoystickAxisAction( int nAxis )

void ClearActionMaps()

Point GetMousePoint()

int GetMouseX()

int GetMouseY()

int GetMouseZ()

int GetJoystickX( )

int GetJoystickY( )

int GetJoystickNormalX( )

int GetJoystickNormalY( )

int GetJoystickZ( )

bool GetJoystickButton( int nIndex )

int GetJoystickSlider( int nIndex )

void Dispose()

 

Poll方法被游戏应用每一帧调用一次。此方法测试每一个硬件设备来取得输入,然后它检查action映射里的每个实体,看是否有被映射的函数需要被调用。如果是,则调用函数来响应玩家的动作。对于一个特殊的轴action的情况呢,函数则使用轴的当前值调用自己(In the case of the actions for a particular axis, the functions are called every time with the current value for that axis)。列表2-4中的这段代码位于Poll方法中,用来处理action映射。

列表2.4action映射处理

foreach ( AxisMapping map in m_AxisActionMap )

{

   switch ( map.key )

   {

      case 0:

         map.action(m_mousedata.X);

         break;

      case 1:

         map.action(m_mousedata.Y);

         break;

      case 2:

         map.action(m_mousedata.Z) ;

         break;

      case 3:

         map.action(m_joystick.X);

         break;

      case 4:

         map.action(m_joystick.X);

         break;

      case 5:

         map.action(m_joystick.X);

         break;

   }

}

// Only process the action map if the console is not visible.

if ( !Game Engine.Console.IsVisible )

{

   foreach ( Mapping map in m_ActionMap )

   {

      // If this mapping is against the keyboard

      if ( map.key <256 )

      {

          // take the action if the key is down or transitioning.

         if ( m_keydata[(Key)map.key] )

        {

            if ( !map.bOnTransition | | oldkeydata[(Key)map.key] )

var cpro_id = "u6885494";

推荐阅读
author-avatar
事过人空
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有