cocos2dx 2.2.6 android 添加按键响应

针对于标准的按键android和win32平台一,cocos2dx 2.2.6版本android平台,引擎原生支持back键,menu键win32平台,引擎原生支持Esc(与back键一致)键需求:遥控器,最常用的操作是上下左右的方向键,确认键,还有返回键,一共六个键。
1,修改引擎底层代码:(1)cocos2dx\keypad_dispatcher\CCKeypadDelegate.h中为CCKeypadDelegate添加按键响应的虚函数class CC_DLL CCKeypadDelegate
{
public:
// The back key clicked
virtual void keyBackClicked() {}

// The menu key clicked. only available on wophone & android
virtual void keyMenuClicked() {};


// The enter key clicked. only available on win32 & android  
virtual void keyEnterClicked() {};


// The arrow key clicked. only available on win32 & android  
virtual void keyArrowClicked(int arrow) {};

};
keyEnterClicked响应中间键(确认键);keyArrowClicked响应方向键。

(2)cocos2dx\keypad_dispatcher\CCKeypadDispatcher.h中添加ccKeypadMSGType枚举值,完整如下:typedef enum { // the back key clicked msg kTypeBackClicked = 1, kTypeMenuClicked,
// the Enter key clicked msg kTypeEnterClicked,
// the arrow key clicked msg kTypeLeftArrowClicked, kTypeUpArrowClicked, kTypeRightArrowClicked, kTypeDownArrowClicked,} ccKeypadMSGType;Enter为中间键(确认键);Arrow为方向键。
(3)cocos2dx\keypad_dispatcher\CCKeypadDispatcher.cpp中dispatchKeypadMSG(ccKeypadMSGType nMsgType)添加响应
switch (nMsgType)
{
case kTypeBackClicked:
pDelegate->keyBackClicked();
break;
case kTypeMenuClicked:
pDelegate->keyMenuClicked();
break;
case kTypeEnterClicked:
pDelegate->keyEnterClicked();
break;
case kTypeLeftArrowClicked:
case kTypeUpArrowClicked:
case kTypeRightArrowClicked:
case kTypeDownArrowClicked:
pDelegate->keyArrowClicked(nMsgType);
break;
default:
break;
}

2,针对平台的修改(1)android平台1)cocos2dx\platform\android\java\src\org\cocos2dx\lib\Cocos2dxGLSurfaceView.java中
onKeyDown函数中添加响应的枚举类型,具体如下:

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);
    }
}

注意后面5个枚举类型的值,这里是以16进制表示的,要跟后面的配置对应。
2)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

注意跟1)中的相关值对应起来。这个地方用的是10进制表示的。
3)cocos2dx\platform\android\jni\TouchesJni.cpp中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;
}

(2)win32平台cocos2dx\platform\win32\CCEGLView.cpp中函数LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)中
case WM_KEYDOWN:
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));
}

3,按键监听的使用如同返回键的使用实现虚函数 virtual void keyEnterClicked();
virtual void keyArrowClicked(int arrow);
开启按键监听setKeypadEnabled(true);

4,后记win32可以作为android相关盒子的调试来使用。毕竟键盘要比遥控器方便得多。

:2::2::2::2::2::2::2:

cocos2dx 3.8+按键响应,引擎本身已经做得比较好了。win32下按键都有响应。android如果要自定义,只需要类似的,添加以下几处就够了。

blablablabla……