最近有个机顶盒项目,需要用到遥控器的方向键在游戏中控制方向。
如果是一般Android设备、iOS设备或Win32平台,cocos2d-x提供了“CCAccelerometer”类,可用于游戏控制UI。但由于机顶盒在使用过程中是使用遥控器与玩家交互,而遥控器中缺少GSenser,所以只能暂时使用方向键和中键。好在机顶盒厂家使用了Android标准的键值,方向键和中键与Andriod DPAD按键一一对应。
下面讲一下如何修改cocos2d-x,以使我们在游戏中能感知DPAD按键消息。
一 修改cocos2dx\keypad_dispatcher\CCKeypadDelegate.h
为” CCKeypadDelegate”添加2个虚函数,完成后为:
- class CC_DLL CCKeypadDelegate
- {
- public:
-
- virtual void keyBackClicked() {}
-
-
- virtual void keyMenuClicked() {};
-
-
- virtual void keyEnterClicked() {};
-
-
- virtual void keyArrowClicked(int arrow) {};
- };
其中” keyEnterClicked”函数用于响应”Enter”键,”keyArrowClicked”函数用于响应方向键消息。
二 cocos2dx\keypad_dispatcher\CCKeypadDispatcher.h
修改枚举 ccKeypadMSGType的定义为:
- typedef enum {
-
- kTypeBackClicked = 1,
-
- kTypeMenuClicked,
-
- kTypeEnterClicked,
-
- kTypeLeftArrowClicked,
- kTypeUpArrowClicked,
- kTypeRightArrowClicked,
- kTypeDownArrowClicked,
- } ccKeypadMSGType;
三 cocos2dx\keypad_dispatcher\CCKeypadDispatcher.cpp
修改” dispatchKeypadMSG”函数,在:
- case kTypeMenuClicked:
- pDelegate->keyMenuClicked();
后添加:
- case kTypeEnterClicked:
- pDelegate->keyEnterClicked();
- break;
- case kTypeLeftArrowClicked:
- case kTypeUpArrowClicked:
- case kTypeRightArrowClicked:
- case kTypeDownArrowClicked:
- pDelegate->keyArrowClicked(nMsgType);
- break;
针对Android平台还需要一下修改:
四 cocos2dx\platform\android\java\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java
找到” onKeyDown”函数,在其中添加几个键值处理,使函数如下:
- @Override
- public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
- switch (pKeyCode) {
- case KeyEvent.KEYCODE_BACK:
- case KeyEvent.KEYCODE_MENU:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- this.queueEvent(new Runnable() {
- @Override
- public void run() {
- Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);
- }
- });
- return true;
- default:
- return super.onKeyDown(pKeyCode, pKeyEvent);
- }
- }
*注意:项目目录中proj.android\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java需要修改与此相同。
五 cocos2dx\platform\android\jni\TouchesJni.cpp
找到:
- #define KEYCODE_BACK 0x04
- #define KEYCODE_MENU 0x52
紧接着在下面添加:
- #define KEYCODE_DPAD_UP 19
- #define KEYCODE_DPAD_DOWN 20
- #define KEYCODE_DPAD_LEFT 21
- #define KEYCODE_DPAD_RIGHT 22
- #define KEYCODE_DPAD_CENTER 23
然后修改”Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown”函数,如下:
- JNIEXPORT jboolean JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown(JNIEnv * env, jobject thiz, jint keyCode) {
- CCDirector* pDirector = CCDirector::sharedDirector();
- switch (keyCode) {
- case KEYCODE_BACK:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked))
- return JNI_TRUE;
- break;
- case KEYCODE_MENU:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeMenuClicked))
- return JNI_TRUE;
- break;
- case KEYCODE_DPAD_UP:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeUpArrowClicked))
- return JNI_TRUE;
- break;
- case KEYCODE_DPAD_DOWN:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeDownArrowClicked))
- return JNI_TRUE;
- break;
- case KEYCODE_DPAD_LEFT:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeLeftArrowClicked))
- return JNI_TRUE;
- break;
- case KEYCODE_DPAD_RIGHT:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeRightArrowClicked))
- return JNI_TRUE;
- break;
- case KEYCODE_DPAD_CENTER:
- if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeEnterClicked))
- return JNI_TRUE;
- break;
- default:
- return JNI_FALSE;
- }
- return JNI_FALSE;
- }
至此Android平台修改完成。
为了方便我们在VS2010中开发,还有针对Win32平台进行修改:
六 cocos2dx\platform\win32\CCEGLView.cpp
找到”WindowProc”函数,找到:
- if (wParam == VK_F1 || wParam == VK_F2)
- {
- CCDirector* pDirector = CCDirector::sharedDirector();
- if (GetKeyState(VK_LSHIFT) < 0 || GetKeyState(VK_RSHIFT) < 0 || GetKeyState(VK_SHIFT) < 0)
- pDirector->getKeypadDispatcher()->dispatchKeypadMSG(wParam == VK_F1 ? kTypeBackClicked : kTypeMenuClicked);
- }
- else if (wParam == VK_ESCAPE)
- {
- CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked);
- }
紧接着在后边添加:
- else if (wParam == VK_RETURN)
- {
- CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeEnterClicked);
- }
- else if (wParam >= VK_LEFT && wParam <= VK_DOWN)
- {
- CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG((ccKeypadMSGType)(kTypeLeftArrowClicked + wParam - VK_LEFT));
- }
好,现在Win32平台也添加完成了,程序中可以响应键盘上的方向键和回车键。
使用方法如下:
假设我们要在继承自CCLayer的HelloWorld中相应按键,那么首先在HelloWorld的头文件中添加两个函数:
- void keyArrowClicked(int arrow);
- void keyEnterClicked();
然后,在HelloWorld初始化时启用按键功能:
在HelloWorld中实现之前声明的2个虚函数:
- void LLPlaneControlLayer::keyArrowClicked(int arrow)
- {
- if (arrow == kTypeLeftArrowClicked)
- {
-
- }
- else if (arrow == kTypeRightArrowClicked)
- {
-
- }
-
- if (arrow == kTypeUpArrowClicked)
- {
-
- }
- else if (arrow == kTypeDownArrowClicked)
- {
-
- }
- }
-
- void LLPlaneControlLayer::keyEnterClicked()
- {
-
- }
当用户按下方向键,keyArrowClicked会被执行,参数arrow表示按下的键;当用户按下Enter键(Android平台为DPAD_CENTER键),keyEnterClicked函数会执行。