关闭

cocos2d-x中添加Enter键和方向键按键响应

3657人阅读 评论(1) 收藏 举报
分类:
 547人阅读

最近有个机顶盒项目,需要用到遥控器的方向键在游戏中控制方向。

如果是一般Android设备、iOS设备或Win32平台,cocos2d-x提供了“CCAccelerometer”类,可用于游戏控制UI。但由于机顶盒在使用过程中是使用遥控器与玩家交互,而遥控器中缺少GSenser,所以只能暂时使用方向键和中键。好在机顶盒厂家使用了Android标准的键值,方向键和中键与Andriod DPAD按键一一对应。

下面讲一下如何修改cocos2d-x,以使我们在游戏中能感知DPAD按键消息。

一 修改cocos2dx\keypad_dispatcher\CCKeypadDelegate.h

为” CCKeypadDelegate”添加2个虚函数,完成后为:

  1. class CC_DLL CCKeypadDelegate  
  2. {  
  3. public:  
  4.     // The back key clicked  
  5.     virtual void keyBackClicked() {}  
  6.   
  7.     // The menu key clicked. only available on wophone & android  
  8.     virtual void keyMenuClicked() {};  
  9.   
  10.     // The enter key clicked. only available on win32 & android  
  11.     virtual void keyEnterClicked() {};  
  12.   
  13.     // The arrow key clicked. only available on win32 & android  
  14.     virtual void keyArrowClicked(int arrow) {};  
  15. };  

其中” keyEnterClicked”函数用于响应”Enter”键,”keyArrowClicked”函数用于响应方向键消息。

二 cocos2dx\keypad_dispatcher\CCKeypadDispatcher.h

修改枚举 ccKeypadMSGType的定义为:

  1. typedef enum {  
  2.     // the back key clicked msg  
  3.     kTypeBackClicked = 1,  
  4.     // the menu key clicked msg  
  5.     kTypeMenuClicked,  
  6.     // the Enter key clicked msg  
  7.     kTypeEnterClicked,  
  8.     // the arrow key clicked msg  
  9.     kTypeLeftArrowClicked,  
  10.     kTypeUpArrowClicked,  
  11.     kTypeRightArrowClicked,  
  12.     kTypeDownArrowClicked,  
  13. } ccKeypadMSGType;  

三 cocos2dx\keypad_dispatcher\CCKeypadDispatcher.cpp
修改” dispatchKeypadMSG”函数,在:

  1. case kTypeMenuClicked:  
  2.                 pDelegate->keyMenuClicked();  

后添加:

  1. case kTypeEnterClicked:  
  2.         pDelegate->keyEnterClicked();  
  3.         break;  
  4. case kTypeLeftArrowClicked:  
  5. case kTypeUpArrowClicked:  
  6. case kTypeRightArrowClicked:  
  7. case kTypeDownArrowClicked:  
  8.     pDelegate->keyArrowClicked(nMsgType);  
  9.              break;  

针对Android平台还需要一下修改:

四 cocos2dx\platform\android\java\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java
找到” onKeyDown”函数,在其中添加几个键值处理,使函数如下:

[java] view plaincopy
  1. @Override  
  2. public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {  
  3.     switch (pKeyCode) {  
  4.         case KeyEvent.KEYCODE_BACK:  
  5.         case KeyEvent.KEYCODE_MENU:  
  6.         case KeyEvent.KEYCODE_DPAD_UP:      // 19  
  7.         case KeyEvent.KEYCODE_DPAD_DOWN:    // 20  
  8.         case KeyEvent.KEYCODE_DPAD_LEFT:    // 21  
  9.         case KeyEvent.KEYCODE_DPAD_RIGHT:   // 22  
  10.         case KeyEvent.KEYCODE_DPAD_CENTER:  // 23  
  11.             this.queueEvent(new Runnable() {  
  12.                 @Override  
  13.                 public void run() {  
  14.                     Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);  
  15.                 }  
  16.             });  
  17.             return true;  
  18.         default:  
  19.             return super.onKeyDown(pKeyCode, pKeyEvent);  
  20.     }  
  21. }  
*注意:项目目录中proj.android\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java需要修改与此相同。

五 cocos2dx\platform\android\jni\TouchesJni.cpp

找到:

  1. #define KEYCODE_BACK 0x04  
  2. #define KEYCODE_MENU 0x52  

紧接着在下面添加:

  1. #define KEYCODE_DPAD_UP     19  
  2.     #define KEYCODE_DPAD_DOWN   20  
  3.     #define KEYCODE_DPAD_LEFT   21  
  4.     #define KEYCODE_DPAD_RIGHT  22  
  5.     #define KEYCODE_DPAD_CENTER 23  
然后修改”Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown”函数,如下:

  1. JNIEXPORT jboolean JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown(JNIEnv * env, jobject thiz, jint keyCode) {  
  2.     CCDirector* pDirector = CCDirector::sharedDirector();  
  3.     switch (keyCode) {  
  4.         case KEYCODE_BACK:  
  5.               if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked))  
  6.                 return JNI_TRUE;  
  7.             break;  
  8.         case KEYCODE_MENU:  
  9.             if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeMenuClicked))  
  10.                 return JNI_TRUE;  
  11.             break;        
  12.         case KEYCODE_DPAD_UP:  
  13.             if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeUpArrowClicked))  
  14.                 return JNI_TRUE;  
  15.             break;  
  16.         case KEYCODE_DPAD_DOWN:  
  17.             if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeDownArrowClicked))  
  18.                 return JNI_TRUE;  
  19.             break;  
  20.         case KEYCODE_DPAD_LEFT:  
  21.             if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeLeftArrowClicked))  
  22.                 return JNI_TRUE;  
  23.             break;  
  24.         case KEYCODE_DPAD_RIGHT:  
  25.             if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeRightArrowClicked))  
  26.                 return JNI_TRUE;  
  27.             break;       
  28.         case KEYCODE_DPAD_CENTER:  
  29.             if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeEnterClicked))  
  30.                 return JNI_TRUE;  
  31.             break;       
  32.         default:  
  33.             return JNI_FALSE;  
  34.     }  
  35.     return JNI_FALSE;  
  36. }  
至此Android平台修改完成。
为了方便我们在VS2010中开发,还有针对Win32平台进行修改:
六 cocos2dx\platform\win32\CCEGLView.cpp

找到”WindowProc”函数,找到:

  1. if (wParam == VK_F1 || wParam == VK_F2)  
  2.        {  
  3.            CCDirector* pDirector = CCDirector::sharedDirector();  
  4.            if (GetKeyState(VK_LSHIFT) < 0 ||  GetKeyState(VK_RSHIFT) < 0 || GetKeyState(VK_SHIFT) < 0)  
  5.                pDirector->getKeypadDispatcher()->dispatchKeypadMSG(wParam == VK_F1 ? kTypeBackClicked : kTypeMenuClicked);  
  6.        }  
  7.        else if (wParam == VK_ESCAPE)  
  8.        {  
  9.            CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked);  
  10.        }  
紧接着在后边添加:

  1. else if (wParam == VK_RETURN)  
  2. {  
  3.     CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeEnterClicked);  
  4. }  
  5. else if (wParam >= VK_LEFT && wParam <= VK_DOWN)  
  6. {  
  7.     CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG((ccKeypadMSGType)(kTypeLeftArrowClicked + wParam - VK_LEFT));  
  8. }  
好,现在Win32平台也添加完成了,程序中可以响应键盘上的方向键和回车键。

使用方法如下:
假设我们要在继承自CCLayer的HelloWorld中相应按键,那么首先在HelloWorld的头文件中添加两个函数:

  1. void keyArrowClicked(int arrow);  
  2. void keyEnterClicked();  
然后,在HelloWorld初始化时启用按键功能:

  1. setKeypadEnabled(true);  
在HelloWorld中实现之前声明的2个虚函数:

  1. void LLPlaneControlLayer::keyArrowClicked(int arrow)  
  2. {     
  3.     if (arrow == kTypeLeftArrowClicked)  
  4.     {  
  5.         // 左方向键按下  
  6.     }  
  7.     else if (arrow == kTypeRightArrowClicked)  
  8.     {  
  9.         // 右方向键按下  
  10.     }  
  11.       
  12.     if (arrow == kTypeUpArrowClicked)  
  13.     {  
  14.         // 上方向键按下  
  15.     }  
  16.     else if (arrow == kTypeDownArrowClicked)  
  17.     {  
  18.         // 下方向键按下  
  19.     }  
  20. }  
  21.   
  22. void LLPlaneControlLayer::keyEnterClicked()  
  23. {  
  24.     // Enter键按下  
  25. }  
当用户按下方向键,keyArrowClicked会被执行,参数arrow表示按下的键;当用户按下Enter键(Android平台为DPAD_CENTER键),keyEnterClicked函数会执行。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2939929次
    • 积分:25256
    • 等级:
    • 排名:第243名
    • 原创:76篇
    • 转载:1132篇
    • 译文:0篇
    • 评论:312条
    最新评论