C#对戏手柄的编程开发-API篇(1)

前段时间花38初由网上购得了扳平针对北通的USB游戏手柄,这样周末同夜间之休闲时间便足以玩玩孩儿时之SFC与街机模拟游戏了。

 

某日在某某网站上玩一个Flash游戏时,突然想到,如果为能采取手柄来玩Flash游戏,那该多爽
。但可惜的是,目前之Flash都是勿支持对戏手柄进行编程,这不免是Flash中之一个缺憾。。

虽说Flash中莫支持针对游戏手柄进行编程,但我们可以变换种方式,做一个扶植程序(外挂?
),将手柄中的操作事件转换为Flash中而接受的键盘和鼠标操作事件,这样非就可以以游戏手柄来玩Flash游戏了吧?!于是,上网查看了系材料,但也发现只有C++方面的案例,而C#一个吗搜不,这不打困难,自己动手,丰衣足食

 

 

(注:类似这样的功力,网络已经发生备的软件,是一个日本丁出的,叫JoyToKey)

 

对游乐手柄进行操作,大概发生星星点点种植方式:采用系统API或者下DirectInput操作游戏手柄设备。(也许还发出其他方法,但自身之学识范围片,其它方式就是不得而知了)

运系统API是平等种植最简便的主意,因为系统曾救助我们封装好了拥有细节,我们而在先后中定时取游戏手柄设备的状态就可以了(轮循)。

 

操作游戏手柄(杆)的API有以下几个

函数名称 函数说明
joyGetNumDevs 获取当前系统支持的游戏设备数量
joyGetDevCaps 查询获取指定的游戏杆设备以确定其性能
joySetCapture 向系统申请捕获某个游戏设备并定时将该设备的状态值通过消息发送到某个窗口
joyReleaseCapture 释放对某个游戏设备的捕获
joyGetPos 获取游戏设备的坐标位置和按钮状态
joyGetPosEx 获取游戏设备的坐标位置和按钮状态
joyGetThreshold 查询指定的游戏杆设备的当前移动阈值
joySetThreshold 设置指定的游戏杆设备的移动阈值

 

其中,根据调用不同之法子以可分为两栽艺术。

1)被动方式:

    
调用joySetCapture方法,向系统报名对某游戏手柄的捕捉,如果成功申请,系统将会见定时拿之戏手柄的状态信息通过信息方式通报及我们的某窗口及。

2)主动方式:

    
即凡依据我们自己之内需,按需调用joyGetPos或joyGetPosEx方法查询得到有游戏手柄的当前状态。

 

假如当本篇中,我们只要教的但是“被动方式”。

 

joySetCapture方法的C#概念原型如下:

        /// <summary>
        /// 向系统申请捕获某个游戏杆并定时将该设备的状态值通过消息发送到某个窗口
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="uJoyID">指定游戏杆(0-15),它可以是JOYSTICKID1或JOYSTICKID2</param>
        /// <param name="uPeriod">每隔给定的轮询间隔就给应用程序发送有关游戏杆的信息。这个参数是以毫妙为单位的轮询频率。</param>
        /// <param name="fChanged">是否允许程序当操纵杆移动一定的距离后才接受消息</param>
        /// <returns></returns>
        [DllImport("winmm.dll")]
        public static extern int joySetCapture(IntPtr hWnd, int uJoyID, int uPeriod, bool fChanged);

当我们调用此道向系统报名捕获某个游戏手柄后,如果成功,则归JOYERR_NOERROR(值为0),否则回其它值的话语代表申请破产。并且以不再用捕获游戏手柄时如果记调用joyReleaseCapture方法释放捕捉。

 

若果申请成功,系统以会定时(根据uPeriod的价决定时之长度)将游戏手柄的状态为信包形式发送到hWnd对应之窗口界面。所以我们不能不要于次中处理相应的消息(如还写WndProc方法开展拍卖)。

又根据不同的uJoyID值,系统发送的消息号又见面迥然不同,如对于JOYSTICKID1系将会见分别发送以下信息包:

消息号 说明
MM_JOY1MOVE 当手柄的位置已变动或按了某些按钮时,将会发送此消息包。
MM_JOY1BUTTONDOWN 当手柄的A,B,C,D四个按钮中的一个或多个正被按下时,将会发送此消息包。
MM_JOY1BUTTONUP 当手柄的A,B,C,D四个按钮中的一个或多个正被弹起时,将会发送此消息包。

 

设对于JOYSTICKID2
系统发生之音讯包分别吗MM_JOY2MOVE、MM_JOY2BUTTONDOWN、MM_JOY2BUTTONUP!

并且要注意!不管你产生没有发生论游戏手柄上之按钮,系统为会见定时发送MM_JOYXMOVE消息!!

 

哪判断照了哪些键?

在信息包中,游戏手柄的状态信息(按钮状态)分别存储于信息包被的WParam与LParam参数。

1)WParam参数:

对此游戏手柄来说WParam存储的是了左右左右季独方向键外边的保有按钮中时被以下的按钮值,它的值是一个复合值。如它的价值吗JOY_BUTTON1
| JOY_BUTTON2常常,就表明以下之按键是1号和2号按钮。

注意:对于MM_JOYXBUTTONDOWN与MM_JOYXBUTTONUP两独消息,用于判断的按钮值是差于MM_JOYXMOVE的按钮值!!

 

2)LParam参数:

夫参数存储的凡戏手柄的坐标参数,并且这参数的强16各项存储的是Y坐标值,低16个存储的是X坐标值。

如对游戏手柄来说,判断上下左右季个趋势键有没有发于按照下便是透过这个参数进行判断的。如果当四单方向键都无被按下时,表示即戏手柄处于中心坐标中!也就算是X,Y坐标都是于主导点位置上,而当某些方向键被以下经常,X,Y坐标将依据所遵循的键向对应方向偏移。如当随了朝右键,则X坐标向右侧偏移,Y坐标保持在中心点位置,而而依了右、上少只方向键同时按照下,则X坐标向右侧偏移,Y坐标向上偏移。所以我们得以依据LParam参数取得X,Y坐标的价值,然后再冲中心点来判定。参考代码如下:

       /// <summary>
        /// 获取X,Y轴的状态
        /// </summary>
        /// <param name="lParam"></param>
        /// <param name="buttons"></param>
        private void GetXYButtonsStateFromLParam(int lParam, ref JoystickButtons buttons)
        {
            //处理X,Y轴
            int x = lParam & 0x0000FFFF;                //低16位存储X轴坐标
            int y = (int)((lParam & 0xFFFF0000) >> 16); //高16位存储Y轴坐标(不直接移位是为避免0xFFFFFF时的情况)
            int m = 0x7EFF;                             //中心点的值
            if (x > m)
            {
                buttons |= JoystickButtons.Right;
            }
            else if (x < m)
            {
                buttons |= JoystickButtons.Left;
            }
            if (y > m)
            {
                buttons |= JoystickButtons.Down;
            }
            else if (y < m)
            {
                buttons |= JoystickButtons.UP;
            }
        }

 

吓了,对戏手柄的“被动方式”编程就讲解完成了,剩下的即是若怎么采取游玩手柄来落实仿键盘或鼠标的操作了……

PS:如果各位有趣味的可考虑一下怎么落实休闲游手柄的“主动方式”编程开发。

 

演示代码下载:

/Files/kingthy/JoyKeys.rar