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版的按钮响应需求。
一开始接了第三方的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版的按钮响应需求。
相关文章推荐
- 【Cocos2d-x游戏引擎开发笔记(3)】在屏幕上渲染菜单并添加消息响应
- Cocos2d-iphone 为sprite添加双击的事件响应
- cocos2d-x中添加Enter键和方向键按键响应
- 【Cocos2d-x游戏引擎开发笔记(3)】在屏幕上渲染菜单并添加消息响应
- cocos2d-x中添加Enter键和方向键按键响应
- cocos2d-x中添加Enter键和方向键按键响应
- cocos2d-x中添加Enter键和方向键按键响应
- cocos2d-x中添加Enter键和方向键按键响应
- 【Cocos2d-x游戏引擎开发笔记(3)】在屏幕上渲染菜单并添加消息响应
- cocos2d-x中添加Enter键和方向键按键响应 (转)
- (转)cocos2d-x中添加Enter键和方向键按键响应
- cocos2d-x中添加Enter键和方向键按键响应
- COCOS2d中添加UIButton不响应触摸事件---iOS开发之最灵异事件之2
- Cocos2d-x 在屏幕上渲染菜单并添加消息响应
- Cocos2d-iphone 为sprite添加双击的事件响应
- Cocos2d-x 在屏幕上渲染菜单并添加消息响应
- Cocos2d-iphone 为sprite添加双击的事件响应
- cocos2d-x中添加TV按键响应
- cocos2d-x中添加Enter键和方向键按键响应
- cocos2d-x 3.3 按钮添加和事件(CCControlButton)