cocos2d-x 响应android TV 遥控器 手柄的添加

刚接了wp8的,又要转接TV版的啦!又是一顿忙活。

一开始接了第三方的android SDK 发现UI线程会被卡死。然后又自己new thread 去跑手柄控制。但是还是会发生cocos2d-x render 上的崩溃。

每次看报告都是崩溃在线程跳转上。最后还是决定用CCkeypadDelegate 的逻辑去实现。

具体实现方式可以参考:http://blog.csdn.net/keshuiyun/article/details/9788533。 感觉博主。

但是还是存在一个小问题。

就是 我这边上下左右无法连续响应。注册OnkeyLongPess 也无法响应。最后采用定时器自己去连续触发的方式。


我的实现方法:

Cocos2dxGLSurfaceView.java 中添加如下函数:

// 

private void runqueueEvent()

{

this.queueEvent(new Runnable() {

@Override

public void run() {

Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(mCurKeyCode);

}

});

}

// 

private void startTimer()

{


if(mTimer ==null)

{

mTimer = new Timer();

}

        if (mTimerTask ==null) {  

            mTimerTask = new TimerTask() {  

                @Override  

                public void run() {  

                //Log.e("TAG","startTimer KeyCode: = "+mCurKeyCode);

                runqueueEvent();

                }  

            };  

        }  

  

        if(mTimer !=null && mTimerTask !=null )  

            mTimer.schedule(mTimerTask,delay, period);

}

    private void stopTimer(){  

        

        if (mTimer !=null) {  

            mTimer.cancel();  

            mTimer = null;  

        }  

  

        if (mTimerTask !=null) {  

            mTimerTask.cancel();  

            mTimerTask = null;  

        }     

    }  

@Override


public boolean onKeyUp(finalint pKeyCode, final KeyEvent pKeyEvent) 

{

Log.e("TAG","onKeyUp KeyCode: = "+pKeyCode);

if(pKeyCode == KeyEvent.KEYCODE_DPAD_LEFT || pKeyCode == KeyEvent.KEYCODE_DPAD_RIGHT){

stopTimer();

}

return super.onKeyUp(pKeyCode, pKeyEvent);

}


public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {

int nRepeatCount = pKeyEvent.getRepeatCount();

    long tempLastClickTime = System.currentTimeMillis();

if ((tempLastClickTime -mLastClickTime) < CD_TIME)

{

returntrue;

}

mLastClickTime = tempLastClickTime;

Log.e("TAG","onKeyDown KeyCode: = "+pKeyCode);

//Log.e("TAG","onKeyDown nRepeatCount: = "+nRepeatCount);

switch (pKeyCode) {

case KeyEvent.KEYCODE_BACK:

case KeyEvent.KEYCODE_MENU:

case KeyEvent.KEYCODE_BUTTON_A:

case KeyEvent.KEYCODE_BUTTON_1:

case KeyEvent.KEYCODE_BUTTON_B:

case KeyEvent.KEYCODE_BUTTON_2:

case KeyEvent.KEYCODE_BUTTON_X:

case KeyEvent.KEYCODE_BUTTON_4:

case KeyEvent.KEYCODE_BUTTON_Y:

case KeyEvent.KEYCODE_BUTTON_3:

case KeyEvent.KEYCODE_DPAD_CENTER:

case KeyEvent.KEYCODE_DPAD_UP:

case KeyEvent.KEYCODE_DPAD_DOWN:

this.queueEvent(new Runnable() {

@Override

public void run() {

Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);

}

});

returntrue;

case KeyEvent.KEYCODE_DPAD_LEFT:

case KeyEvent.KEYCODE_DPAD_RIGHT:

if (nRepeatCount == 0){//左右连续按钮

mCurKeyCode = pKeyCode;

startTimer();

}

else

{

this.queueEvent(new Runnable() {

@Override

public void run() {

Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);

}

});

}

returntrue;

default:

return super.onKeyDown(pKeyCode, pKeyEvent);

}

}

///

   #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
    #define KEYCODE_BUTTON_A     96
    #define KEYCODE_BUTTON_B     97
    #define KEYCODE_BUTTON_X     99
    #define KEYCODE_BUTTON_Y     100
    #define KEYCODE_BUTTON_1     188
    #define KEYCODE_BUTTON_2     189
    #define KEYCODE_BUTTON_3     190
    #define KEYCODE_BUTTON_4     191

 ../cocos2d-x-2.2.4/cocos2dx/platform/android/jni/TouchesJni.cpp 中修改 Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown函数

 CCDirector* pDirector = CCDirector::sharedDirector();
        switch (keyCode) {
            case KEYCODE_BACK:
                  if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked))
                    return JNI_TRUE;
                break;
            case KEYCODE_MENU:

...依次添加就好。

}


 .../cocos2d-x-2.2.4/cocos2dx/keypad_dispatcher/CCKeypadDelegate.h 

添加一个响应按键的虚函数:
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 menu key clicked. only available on wophone & android
    virtual void keyArrowClicked(int nKeyCode) {};
};


../cocos2d-x-2.2.4/cocos2dx/keypad_dispatcher/CCKeypadDispatcher.cpp 添加响应就可以了

bool CCKeypadDispatcher::dispatchKeypadMSG(ccKeypadMSGType nMsgType)
{
    CCKeypadHandler*  pHandler = NULL;
    CCKeypadDelegate* pDelegate = NULL;


    m_bLocked = true;


    if (m_pDelegates->count() > 0)
    {
        CCObject* pObj = NULL;
        CCARRAY_FOREACH(m_pDelegates, pObj)
        {
            CC_BREAK_IF(!pObj);


            pHandler = (CCKeypadHandler*)pObj;
            pDelegate = pHandler->getDelegate();


            switch (nMsgType)
            {
            case kTypeBackClicked:
                pDelegate->keyBackClicked();
                break;
            case kTypeMenuClicked:
                pDelegate->keyMenuClicked();
                break;
            case kTypeButton_A_Clicked:
            case kTypeButton_B_Clicked:
            case kTypeButton_X_Clicked:
            case kTypeButton_Y_Clicked:
            case kTypeUpArrowClicked:
            case kTypeDownArrowClicked:
            case kTypeLeftArrowClicked:
            case kTypeRightArrowClicked:
            case kTypeEnterClicked:
                    pDelegate->keyArrowClicked(nMsgType);
                    break;
            default:
                break;
            }
        }
    }

...剩余部分省略。

}

//还忘记了CCKeypadDispatcher.h 添加枚举按键类型

/**
 * @addtogroup input
 * @{
 */


typedef enum {
    // the back key clicked msg
    kTypeBackClicked = 1,
    kTypeMenuClicked,
    kTypeButton_A_Clicked,
    kTypeButton_B_Clicked,
    kTypeButton_X_Clicked,
    kTypeButton_Y_Clicked,
    kTypeUpArrowClicked,
    kTypeDownArrowClicked,
    kTypeLeftArrowClicked,
    kTypeRightArrowClicked,
    kTypeEnterClicked,
    
    
} ccKeypadMSGType;

///

CClayer.cpp 添加。

void CCLayer::keyArrowClicked(int nKeyCode)
{
    if (m_pScriptKeypadHandlerEntry)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeLayerKeypadEvent(this, nKeyCode);
    }
}


// 这样就实现了
class IntroLayer : public CCLayer...
{
public:

    ....
    virtual void keyArrowClicked(int nKeyCode);

   ...

}

///

我用cocos2d-x 版本是2.2.4的测试可以满足TV版的按钮响应需求。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虾米神探

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值