您的位置:首页 > 移动开发 > Cocos引擎

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

2014-09-24 12:58 435 查看
刚接了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版的按钮响应需求。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: