还是坚持每周一博,照例写正文前废话一段:最近天气越来越好,不下雪了,偶尔下点雨,下了一次冰雹,但可以看到10+的温度了,晚上6点坐车回家的时候天还是是微亮。哈,德国的春天终于来了。
迫于项目时间的压力,项目只剩下最后一周的时间,本周的工作效率还不错,写了非常多的代码,突然发现,我最近最能集中心力,最具生产力的时段是下午5到6点,就是回家前一个小时,似乎所有最有创造力的生产和想法都是在这个小时产生的,很奇怪。最近,所里的咖啡机又坏了,苦了很多人,有一个意大利同事对我说说,没有咖啡就不能Coffee in, Code out,没法编程了。还好我不喝咖啡,每天只喝茶,所里提供的各种奇怪的茶包(德国的茶包的种类真是多的恐怖,各种奇怪的口味都有,喝过一种咖喱口味的茶)。
好了闲话不多谈,今天谈谈关于游戏手柄joystick的代码开发,最近接触了一些多媒体子系统的Win32 API,其实非常容易,通过一些google可以找到非常多的源代码和示例代码,可以非常快的利用多媒体的Win32 API开发出一些很有趣的东西,游戏手柄joystick代码开发就是一个很经典的例子。支持游戏手柄现在是一个Win32的标准的一部分,多媒体子系统单独的Win32 API,其中支持游戏手柄是一个组成部分。但是关于游戏手柄的功能和数据结构没有定义在标准windows.h头文件,而是位于mmsystem.h中头文件。
上代码之前,一些说明:
[1]
要使用游戏手柄的Win32 API
#include <windows.h>
#include <mmsystem.h>
编译器请使用VS2005以上版本。
[2]
当然了不要忘记加入winmm.lib。
[3]
JOYSTATE数据类型包括描述游戏手柄的State
例如
2: const JOYSTATE JOY_NONE = 0x0000L,
3: JOY_LEFT = 0x0001L,
4: JOY_RIGHT = 0x0002L,
5: JOY_UP = 0x0004L,
6: JOY_DOWN = 0x0008L,
[4]
我们要做的事就是,写出以下方法:
void CaptureJoystick();
void ReleaseJoystick();
void CheckJoystick();
[5]
写CaptureJoystick()和 ReleaseJoystick()的方法就是使用使用两个Win32 functions就是:joySetCapture() 和 joyReleaseCapture() 。
JOYINFO structure用于检索游戏手柄状态通过joyGetPos() function。
[6]
以下代码结合了Qt,也可以不需要Qt运行,只需要删除Qt部分的代码即可,使用了Qt的signal slot机制,利用了QTime的timeout()不断对CheckJoystick()进行调用,以及时更新Joystick状态。
[7]
以下的代码的主体部分来自网上的一些示例代码,我进行了一些修改和裁剪,编译和使用没有任何问题,我使用的是北通小手柄 BTP-C024 USB游戏手柄(如附图所示)进行测试,运行很好。以下代码非常简单,应该很容易理解,不要问我,为什么不能用,或者如何使用,如果不能用,请google或再看看代码(你已经有了完整的代码),呵呵。
2 * \file GameEngine.h
3 * \class GameEngine
4 * \date 2010
5 * \bug
6 * \warning
7 *
8 */
9
10 #ifndef GAMEENGINE_H_
11 #define GAMEENGINE_H_
12
13 #include <QtGui>
14
15 #include <windows.h>
16 #include <mmsystem.h>
17
18 //-----------------------------------------------------------------
19 // Joystick Flags
20 //-----------------------------------------------------------------
21 typedef WORD JOYSTATE;
22 const JOYSTATE JOY_NONE = 0x0000L,
23 JOY_LEFT = 0x0001L,
24 JOY_RIGHT = 0x0002L,
25 JOY_UP = 0x0004L,
26 JOY_DOWN = 0x0008L,
27 JOY_FIRE1 = 0x0010L,
28 JOY_FIRE2 = 0x0020L,
29 JOY_FIRE3 = 0x0030L,
30 JOY_FIRE4 = 0x0040L;
31
32 class GameEngine : public QObject
33 {
34 Q_OBJECT
35
36 public:
37
38 GameEngine();
39 ~GameEngine();
40
41 void HandleJoystick(JOYSTATE jsJoystickState);
42
43 BOOL InitJoystick();
44 void CaptureJoystick();
45 void ReleaseJoystick();
46
47 UINT m_uiJoystickID;
48 RECT m_rcJoystickTrip;
49 HWND m_hWindow;
50
51 protected:
52
53 private slots:
54 void CheckJoystick();
55
56 signals:
57 void joystickLeft();
58 void joystickRight();
59 void joystickUp();
60 void joystickDown();
61 void joystickButton1();
62 void joystickButton2();
63 void joystickButton3();
64 void joystickButton4();
65
66 private:
67 QTimer *_poller;
68
69 };
70
71 #endif /* GAMEENGINE_H_ */
2 * \file GameEngine.cpp
3 * \class GameEngine
4 * \date 2010
5 * \bug
6 * \warning
7 *
8 */
9
10 #include <QDebug>
11
12 #include "GameEngine.h"
13
14
15 GameEngine::GameEngine()
16 {
17
18 InitJoystick();
19 CaptureJoystick();
20
21 //start timer to trigger every 100 ms
22 _poller = new QTimer(this);
23 connect(_poller, SIGNAL(timeout()), this, SLOT(CheckJoystick()));
24 _poller->start(100);
25 }
26
27 GameEngine::~GameEngine()
28 {
29
30 }
31
32 BOOL GameEngine::InitJoystick()
33 {
34 // Make sure joystick driver is present
35 UINT uiNumJoysticks;
36 if ((uiNumJoysticks = joyGetNumDevs()) == 0)
37 return FALSE;
38
39 // Make sure the joystick is attached
40 JOYINFO jiInfo;
41 if (joyGetPos(JOYSTICKID1, &jiInfo) != JOYERR_UNPLUGGED)
42 m_uiJoystickID = JOYSTICKID1;
43 else
44 return FALSE;
45
46 // Calculate the trip values
47 JOYCAPS jcCaps;
48 joyGetDevCaps(m_uiJoystickID, &jcCaps, sizeof(JOYCAPS));
49 DWORD dwXCenter = ((DWORD)jcCaps.wXmin + jcCaps.wXmax) / 2;
50 DWORD dwYCenter = ((DWORD)jcCaps.wYmin + jcCaps.wYmax) / 2;
51 m_rcJoystickTrip.left = (jcCaps.wXmin + (WORD)dwXCenter) / 2;
52 m_rcJoystickTrip.right = (jcCaps.wXmax + (WORD)dwXCenter) / 2;
53 m_rcJoystickTrip.top = (jcCaps.wYmin + (WORD)dwYCenter) / 2;
54 m_rcJoystickTrip.bottom = (jcCaps.wYmax + (WORD)dwYCenter) / 2;
55 return TRUE;
56 }
57
58 void GameEngine::CaptureJoystick()
59 {
60 // Capture the joystick
61 if (m_uiJoystickID == JOYSTICKID1)
62 {
63 joySetCapture(m_hWindow, m_uiJoystickID, NULL, TRUE);
64 qDebug() << " Capture Joystick success!";
65 }
66 }
67
68 void GameEngine::ReleaseJoystick()
69 {
70 // Release the joystick
71 if (m_uiJoystickID == JOYSTICKID1)
72 joyReleaseCapture(m_uiJoystickID);
73 }
74
75 void GameEngine::CheckJoystick()
76 {
77 if (m_uiJoystickID == JOYSTICKID1)
78 {
79 JOYINFO jiInfo;
80 JOYSTATE jsJoystickState = 0;
81 if (joyGetPos(m_uiJoystickID, &jiInfo) == JOYERR_NOERROR)
82 {
83 // Check horizontal movement
84 if (jiInfo.wXpos < (WORD)m_rcJoystickTrip.left)
85 jsJoystickState |= JOY_LEFT;
86 else if (jiInfo.wXpos > (WORD)m_rcJoystickTrip.right)
87 jsJoystickState |= JOY_RIGHT;
88 // Check vertical movement
89 if (jiInfo.wYpos < (WORD)m_rcJoystickTrip.top)
90 jsJoystickState |= JOY_UP;
91 else if (jiInfo.wYpos > (WORD)m_rcJoystickTrip.bottom)
92 jsJoystickState |= JOY_DOWN;
93 // Check buttons
94 if(jiInfo.wButtons & JOY_BUTTON1)
95 jsJoystickState |= JOY_FIRE1;
96 if(jiInfo.wButtons & JOY_BUTTON2)
97 jsJoystickState |= JOY_FIRE2;
98 if(jiInfo.wButtons & JOY_BUTTON3)
99 jsJoystickState |= JOY_FIRE3;
100 if(jiInfo.wButtons & JOY_BUTTON4)
101 jsJoystickState |= JOY_FIRE4;
102 }
103
104 // Allow the game to handle the joystick
105 HandleJoystick(jsJoystickState);
106 }
107 }
108
109 void GameEngine::HandleJoystick(JOYSTATE jsJoystickState)
110 {
111 //这里加入你自己对jsJoystickState的处理,以下只是极简单的示范
112 //通过HandleJoystick得到JOYSTATE
113
114 //qDebug() << " get information about Joystick!" ;
115 if (jsJoystickState == JOY_UP)
116 {
117 qDebug() << " get Joystick -- JOY_UP!" ;
118 }
119 else if (jsJoystickState == JOY_DOWN)
120 {
121 qDebug() << " get Joystick -- JOY_DOWN!" ;
122 }
123 else if (jsJoystickState == JOY_LEFT)
124 {
125 qDebug() << " get Joystick -- JOY_LEFT!" ;
126 }
127 else if (jsJoystickState == JOY_RIGHT)
128 {
129 qDebug() << " get Joystick -- JOY_RIGHT!" ;
130 }
131 else if (jsJoystickState == JOY_FIRE1)
132 {
133 qDebug() << " get Joystick -- JOY_FIRE1!" ;
134 }
135 else if (jsJoystickState == JOY_FIRE2)
136 {
137 qDebug() << " get Joystick -- JOY_FIRE2!" ;
138 }
139 else if (jsJoystickState == JOY_FIRE3)
140 {
141 qDebug() << " get Joystick -- JOY_FIRE3!" ;
142 }
143 else if (jsJoystickState == JOY_FIRE4)
144 {
145 qDebug() << " get Joystick -- JOY_FIRE4!" ;
146 }
147 }
148
Enjoy!
没有评论:
发表评论