在使用cocos2dx制作游戏的时候,为了提高android用户的使用,添加了android的按键监听,并且所有的界面联动都监听了bank按键。但是在使用的时候发现,两个layer监听实体键之后都收到了实体键返回。cocos并没有对实体键的反馈做事件消耗。好吧,引擎不做的只好自己实现了。

参考网页

感谢大神c++实现方案
cocos2dx-3.0+的按键事件处理还是不尽如人意–cocoachina
本文主要是实现lua层和对大神方案的补充,如果有错误还请各位路过大神指点指点,本人将不胜感激

实现

按大神指导修改文件

  • CCEventListener.h
bool init(Type t, const ListenerID& listenerID, const std::function<bool(Event*)>& callback);//修改
std::function<bool(Event*)> _onEvent;   //修改
  • CCEventListener.cpp
bool EventListener::init(Type t, const ListenerID& listenerID, const std::function<bool(Event*)>& callback)//修改
  • CCEventDispatcher.cpp
void EventDispatcher::dispatchEvent(Event* event){    if (!_isEnabled)        return;    updateDirtyFlagForSceneGraph();    DispatchGuard guard(_inDispatch);    if (event->getType() == Event::Type::TOUCH)    {        dispatchTouchEvent(static_cast(event));        return;    }    auto listenerID = __getListenerID(event);    sortEventListeners(listenerID);    auto pfnDispatchEventToListeners = &EventDispatcher::dispatchEventToListeners;    if (event->getType() == Event::Type::MOUSE) {        pfnDispatchEventToListeners = &EventDispatcher::dispatchTouchEventToListeners;    }    auto iter = _listenerMap.find(listenerID);    if (iter != _listenerMap.end())    {        auto listeners = iter->second;        auto onEvent = [&event](EventListener* listener) -> bool{            event->setCurrentTarget(listener->getAssociatedNode());            //listener->_onEvent(event);//修改位置            //return event->isStopped();            return listener->_onEvent(event) || event->isStopped();        };        (this->*pfnDispatchEventToListeners)(listeners, onEvent);    }    updateListeners(event);}
  • CCEventListenerKeyboard.h
std::function<void(EventKeyboard::KeyCode, Event*)> onKeyReleased;//修改
  • CCEventListenerKeyboard.cpp
bool EventListenerKeyboard::init(){    auto listener = [this](Event* event)->bool{//修改位置        auto keyboardEvent = static_cast(event);        if (keyboardEvent->_isPressed)        {            if (onKeyPressed != nullptr)               onKeyPressed(keyboardEvent->_keyCode, event);        }        else        {            if (onKeyReleased != nullptr)                return onKeyReleased(keyboardEvent->_keyCode, event);//修改位置        }        return false;//修改位置    };    if (EventListener::init(Type::KEYBOARD, LISTENER_ID, listener))    {        return true;    }    return false;}
  • CCEventListenerAcceleration.cpp
bool EventListenerAcceleration::init(const std::function<void(Acceleration*, Event* event)>& callback){    auto listener = [this](Event* event)->bool{//修改位置        auto accEvent = static_cast(event);        this->onAccelerationEvent(&accEvent->_acc, event);        return event->isStopped();//修改位置    };    if (EventListener::init(Type::ACCELERATION, LISTENER_ID, listener))    {        onAccelerationEvent = callback;        return true;    }    return false;}
  • CCEventListenerController.cpp
bool EventListenerController::init(){    auto listener = [this](Event* event)->bool{//修改位置        auto evtController = static_cast(event);        switch (evtController->getControllerEventType())        {        case EventController::ControllerEventType::CONNECTION:            if (evtController->isConnected())            {                if (this->onConnected)                    this->onConnected(evtController->getController(), event);            }            else            {                if (this->onDisconnected)                    this->onDisconnected(evtController->getController(), event);            }            break;        case EventController::ControllerEventType::BUTTON_STATUS_CHANGED:            {                const auto&  keyStatus = evtController->_controller->_allKeyStatus[evtController->_keyCode];                const auto&  keyPrevStatus = evtController->_controller->_allKeyPrevStatus[evtController->_keyCode];                if (this->onKeyDown && keyStatus.isPressed && !keyPrevStatus.isPressed)                {                    this->onKeyDown(evtController->_controller, evtController->_keyCode, event);                }                else if (this->onKeyUp && !keyStatus.isPressed && keyPrevStatus.isPressed)                {                    this->onKeyUp(evtController->_controller, evtController->_keyCode, event);                }                else if (this->onKeyRepeat && keyStatus.isPressed && keyPrevStatus.isPressed)                {                    this->onKeyRepeat(evtController->_controller, evtController->_keyCode, event);                }            }            break;        case EventController::ControllerEventType::AXIS_STATUS_CHANGED:            {                if (this->onAxisEvent)                {                    this->onAxisEvent(evtController->_controller, evtController->_keyCode, event);                }            }            break;        default:            CCASSERT(false, "Invalid EventController type");            break;        }        return event->isStopped();//修改位置    };    if (EventListener::init(EventListener::Type::GAME_CONTROLLER, LISTENER_ID, listener))    {        return true;    }    return false;}
  • CCEventListenerCustom.cpp
bool EventListenerCustom::init(const ListenerID& listenerId, const std::function<void(EventCustom*)>& callback){    bool ret = false;    _onCustomEvent = callback;    auto listener = [this](Event* event)->bool {//修改位置        if (_onCustomEvent != nullptr)        {            _onCustomEvent(static_cast(event));        }        return event->isStopped();//修改位置    };    if (EventListener::init(EventListener::Type::CUSTOM, listenerId, listener))    {        ret = true;    }    return ret;}
  • CCEventListenerFocus.cpp
bool EventListenerFocus::init(){    auto listener = [this](Event* event)->bool{//修改位置        auto focusEvent = static_cast(event);        onFocusChanged(focusEvent->_widgetLoseFocus, focusEvent->_widgetGetFocus);        return event->isStopped();//修改位置    };    if (EventListener::init(Type::FOCUS, LISTENER_ID, listener)) {        return true;    }    return false;}
  • CCEventListenerMouse.cpp
bool EventListenerMouse::init(){    auto listener = [this](Event* event)->bool{//修改位置        auto mouseEvent = static_cast(event);        switch (mouseEvent->_mouseEventType)        {            case EventMouse::MouseEventType::MOUSE_DOWN:                if(onMouseDown != nullptr)                    onMouseDown(mouseEvent);                break;            case EventMouse::MouseEventType::MOUSE_UP:                if(onMouseUp != nullptr)                    onMouseUp(mouseEvent);                break;            case EventMouse::MouseEventType::MOUSE_MOVE:                if(onMouseMove != nullptr)                    onMouseMove(mouseEvent);                break;            case EventMouse::MouseEventType::MOUSE_SCROLL:                if(onMouseScroll != nullptr)                    onMouseScroll(mouseEvent);                break;            default:                break;        }        return event->isStopped();//修改位置    };    if (EventListener::init(Type::MOUSE, LISTENER_ID, listener))    {        return true;    }    return false;}
  • CCInputDelegate.h
virtual bool onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event) { return false; }; //修改
  • UIWidget.cpp
bool onKeypadKeyPressed(EventKeyboard::KeyCode, Event*);//修改
bool Widget::FocusNavigationController::onKeypadKeyPressed(EventKeyboard::KeyCode  keyCode, Event *event){    if (_enableFocusNavigation && _firstFocusedWidget)    {        if (keyCode == EventKeyboard::KeyCode::KEY_DPAD_DOWN)        {            _firstFocusedWidget = _firstFocusedWidget->findNextFocusedWidget(Widget::FocusDirection::DOWN, _firstFocusedWidget);        }        if (keyCode == EventKeyboard::KeyCode::KEY_DPAD_UP)        {            _firstFocusedWidget = _firstFocusedWidget->findNextFocusedWidget(Widget::FocusDirection::UP, _firstFocusedWidget);        }        if (keyCode == EventKeyboard::KeyCode::KEY_DPAD_LEFT)        {            _firstFocusedWidget = _firstFocusedWidget->findNextFocusedWidget(Widget::FocusDirection::LEFT, _firstFocusedWidget);        }        if (keyCode == EventKeyboard::KeyCode::KEY_DPAD_RIGHT)        {            _firstFocusedWidget = _firstFocusedWidget->findNextFocusedWidget(Widget::FocusDirection::RIGHT, _firstFocusedWidget);        }    }    return event->isStopped();//修改位置}
  • CCLayer.h
virtual bool onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);//修改
  • CCLayer.cpp
bool Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* unused_event){    CC_UNUSED_PARAM(unused_event);#if CC_ENABLE_SCRIPT_BINDING    if(kScriptTypeNone != _scriptType)    {        KeypadScriptData data(keyCode, this);        ScriptEvent event(kKeypadEvent,&data);        return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);//修改位置    }#endif    return false;//修改位置}
  • lua_cocos2dx_manual.cpp
static int lua_cocos2dx_Layer_setKeyboardEnabled(lua_State* L){    if (nullptr == L)        return 0;    int argc = 0;    Layer* self = nullptr;#if COCOS2D_DEBUG >= 1    tolua_Error tolua_err;    if (!tolua_isusertype(L,1,"cc.Layer",0,&tolua_err)) goto tolua_lerror;#endif    self = static_cast(tolua_tousertype(L,1,0));#if COCOS2D_DEBUG >= 1    if (nullptr == self) {        tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setKeyboardEnabled'\n", NULL);        return 0;    }#endif    argc = lua_gettop(L) - 1;    if (1 == argc)    {#if COCOS2D_DEBUG >= 1        if (!tolua_isboolean(L, 2, 0, &tolua_err))            goto tolua_lerror;#endif        bool enabled = tolua_toboolean(L, 2, 0);        auto dict = static_cast<__Dictionary*>(self->getUserObject());        if (dict == nullptr)        {            dict = __Dictionary::create();            self->setUserObject(dict);        }        dict->setObject(__Bool::create(enabled), "keyboardEnabled");        auto keyboardListener = static_cast(dict->objectForKey("keyboardListener"));        auto dispatcher = self->getEventDispatcher();        dispatcher->removeEventListener(keyboardListener);        if (enabled)        {            auto listener = EventListenerKeyboard::create();            listener->onKeyPressed = [self](EventKeyboard::KeyCode keyCode, Event* event){            };            listener->onKeyReleased = [self](EventKeyboard::KeyCode keyCode, Event* event){                KeypadScriptData data(keyCode, self);                ScriptEvent scriptEvent(kKeypadEvent,&data);                return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent);//修改位置            };            CCLOG("come in the keyboardEnable");            dispatcher->addEventListenerWithSceneGraphPriority(listener, self);            dict->setObject(listener, "keyboardListener");        }        return 0;    }    luaL_error(L, "%s has wrong number of arguments: %d, was expecting %d\n", "cc.Layer:setKeyboardEnabled", argc, 1);    return 0;#if COCOS2D_DEBUG >= 1tolua_lerror:    tolua_error(L,"#ferror in function 'lua_cocos2dx_Layer_setKeyboardEnabled'.",&tolua_err);    return 0;#endif}
static void cloneKeyboardHandler(const EventListenerKeyboard* src,EventListenerKeyboard* dst,  ScriptHandlerMgr::HandlerType type){    if (nullptr == src || nullptr == dst)        return;    LUA_FUNCTION handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)src, type);    if (0 != handler)    {        int newscriptHandler = cocos2d::ScriptEngineManager::getInstance()->getScriptEngine()->reallocateScriptHandler(handler);        ScriptHandlerMgr::getInstance()->addObjectHandler((void*)dst, newscriptHandler, type);        switch (type)        {            case ScriptHandlerMgr::HandlerType::EVENT_KEYBOARD_PRESSED:                {                    dst->onKeyPressed = [=](EventKeyboard::KeyCode keyCode, Event* event){                        LuaEventKeyboarData listenerData((int)keyCode, event);                        BasicScriptData data((void*)dst,(void*)&listenerData);                        LuaEngine::getInstance()->handleEvent(type, (void*)&data);                    };                }                break;            case ScriptHandlerMgr::HandlerType::EVENT_KEYBOARD_RELEASED:                {                    dst->onKeyReleased = [=](EventKeyboard::KeyCode keyCode, Event* event){                        LuaEventKeyboarData listenerData((int)keyCode, event);                        BasicScriptData data((void*)dst,(void*)&listenerData);                        return LuaEngine::getInstance()->handleEvent(type, (void*)&data);//修改位置                    };                }                break;            default:                break;        }    }}
static int tolua_cocos2dx_EventListenerKeyboard_registerScriptHandler(lua_State* tolua_S){    if (nullptr == tolua_S)        return 0;    int argc = 0;    EventListenerKeyboard* self = nullptr;#if COCOS2D_DEBUG >= 1    tolua_Error tolua_err;    if (!tolua_isusertype(tolua_S, 1, "cc.EventListenerKeyboard", 0, &tolua_err))  goto tolua_lerror;#endif    self = static_cast(tolua_tousertype(tolua_S,1,0));#if COCOS2D_DEBUG >= 1    if (nullptr == self) {        tolua_error(tolua_S,"invalid 'self' in function 'tolua_cocos2dx_EventListenerKeyboard_registerScriptHandler'\n", nullptr);        return 0;    }#endif    argc = lua_gettop(tolua_S) - 1;    if (argc == 2)    {#if COCOS2D_DEBUG >= 1        if (!toluafix_isfunction(tolua_S,2,"LUA_FUNCTION",0,&tolua_err) ||            !tolua_isnumber(tolua_S, 3, 0, &tolua_err))        {            goto tolua_lerror;        }#endif        LUA_FUNCTION handler = toluafix_ref_function(tolua_S,2,0);        ScriptHandlerMgr::HandlerType type = static_cast((int)tolua_tonumber(tolua_S, 3, 0));        switch (type)        {            case ScriptHandlerMgr::HandlerType::EVENT_KEYBOARD_PRESSED:                {                    ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);                    self->onKeyPressed = [=](EventKeyboard::KeyCode keyCode, Event* event){                        LuaEventKeyboarData listenerData((int)keyCode, event);                        BasicScriptData data((void*)self,(void*)&listenerData);                        LuaEngine::getInstance()->handleEvent(type, (void*)&data);                    };                }                break;            case ScriptHandlerMgr::HandlerType::EVENT_KEYBOARD_RELEASED:                {                    ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);                    self->onKeyReleased = [=](EventKeyboard::KeyCode keyCode, Event* event){                        LuaEventKeyboarData listenerData((int)keyCode, event);                        BasicScriptData data((void*)self,(void*)&listenerData);                        return LuaEngine::getInstance()->handleEvent(type, (void*)&data);//修改位置                    };                }                break;            default:                break;        }        return 0;    }    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d\n", "cc.EventListenerKeyboard:registerScriptHandler", argc, 2);    return 0;#if COCOS2D_DEBUG >= 1tolua_lerror:    tolua_error(tolua_S,"#ferror in function 'tolua_cocos2dx_EventListenerKeyboard_registerScriptHandler'.",&tolua_err);    return 0;#endif}

代码修改完成,快去试试效果吧!

更多相关文章

  1. 浅析Android(安卓)App的相对布局RelativeLayout
  2. 程序媛也话Android(安卓)之 自定义控件(垂直方向滑动条)
  3. InputFilter实现EditText文本输入过滤器
  4. Android(安卓)弹无虚发之第五弹:来点儿不一样的Toast(自定义Toast,
  5. Android招财进宝手势密码的实现
  6. Android(安卓)Studio 错误: 编码GBK的不可映射字符;gradle projec
  7. Android:EditText属性大全
  8. Android(安卓)View 随手指移动
  9. Programming access to Android(安卓)Market

随机推荐

  1. Android(安卓)- 手机开发调试无法输出log
  2. Ubuntu16.04 LTS安装Android(安卓)studio
  3. Android(安卓)adb不是内部或外部命令 问
  4. Android(安卓)View(一)
  5. Android(安卓)开源动画框架:NineOldAndroi
  6. Android底部导航栏+消息提醒
  7. Android(安卓)数据存储之SharedPreferenc
  8. 《大话移动APP测试:Android与iOS应用测试
  9. Android语音识别编程初步
  10. Android(安卓)studio添加httpclient的jar