[cocos2dx笔记010]用于UI的事件管理器

来源:互联网 发布:编辑录音的软件 编辑:程序博客网 时间:2024/05/16 08:32

cocos2dx有一个编辑器:cocostudio,目前来说,已经是比较好用了,只要加载导出的资源,就可以用上了。省去手动搭建面的麻烦。但是,很多需要事件的地方,操作比较麻烦,所以这里提供一个事件管理器来集中和简化管理事件。对于C++事件委托方面,我这里使用了是FastDelegate(注:一个牛人写的)。下面是具体实现的代理,不多。

/*UI触摸事件管理器。原有cocos2dx带的触摸事件,每次监听要操作的步骤比较多,为此增加了一个事件管理器,来集中和简化管理*/#ifndef _X_TOUCH_EVENT_MANAGER_H_#define _X_TOUCH_EVENT_MANAGER_H_#include <cocos2d.h>#include <cocos-ext.h>#include <FastDelegate.h>#include <xmap.h>#include <xlog.h>namespace zdh{USING_NS_CC;USING_NS_CC_EXT;class XTouchEventManager : public CCObject{public://绑定的事件定义typedef fastdelegate::FastDelegate<void(gui::Widget *, gui::TouchEventType)> TTouchEvent;typedef int TagID_t;//一个Tag的触模事件结构,包括了四个事件struct STagEvent{TTouchEvent EventBegin;TTouchEvent EventMoved;TTouchEvent EventEnded;TTouchEvent EventCanceled;TTouchEvent * getByType(gui::TouchEventType paramType){switch (paramType){case gui::TOUCH_EVENT_BEGAN:return &EventBegin;case gui::TOUCH_EVENT_MOVED:return &EventMoved;case gui::TOUCH_EVENT_ENDED:return &EventEnded;case gui::TOUCH_EVENT_CANCELED:return &EventCanceled;}return nullptr;}//判断事件是不是都是为空bool isAllEmpty() const{return EventBegin.empty()&& EventEnded.empty()&& EventMoved.empty()&& EventCanceled.empty();}};//Tag事件映射表,可以换用std::maptypedef XMap<TagID_t, STagEvent> TEventMap;public:XTouchEventManager():m_UI(nullptr){}static XTouchEventManager * create(){XTouchEventManager * pRet = new XTouchEventManager();pRet->autorelease();return pRet;}//propertyvoid setUI(gui::TouchGroup * paramUI){m_UI = paramUI;}gui::TouchGroup * getUI(){return m_UI;}//绑定一个指定Tag和事件类型的事件TTouchEvent * Bind(TagID_t paramTagID, gui::TouchEventType paramType){if (!(paramType == gui::TOUCH_EVENT_BEGAN|| paramType == gui::TOUCH_EVENT_CANCELED|| paramType == gui::TOUCH_EVENT_ENDED|| paramType == gui::TOUCH_EVENT_MOVED))  return nullptr;int iIndex = m_Map.getIndexBykey(paramTagID);if (m_Map.isValidIndex(iIndex)){return m_Map.getValue(iIndex).getByType(paramType);}else{gui::Widget * pWidget = GetNodeByTag(paramTagID);if (isNULL(pWidget)) return nullptr;pWidget->addTouchEventListener(this, gui::SEL_TouchEvent(&XTouchEventManager::OnUITouch));return m_Map[paramTagID].getByType(paramType);}}//移除指定Tag和事件类型的侦听void RemoveListen(TagID_t paramTagID, gui::TouchEventType paramType){if (!(paramType == gui::TOUCH_EVENT_BEGAN|| paramType == gui::TOUCH_EVENT_CANCELED|| paramType == gui::TOUCH_EVENT_ENDED|| paramType == gui::TOUCH_EVENT_MOVED))  return;int iIndex = m_Map.getIndexBykey(paramTagID);if (m_Map.isValidIndex(iIndex)){auto pV = m_Map.getValue(iIndex);pV.getByType(paramType)->clear();if (pV.isAllEmpty())  //如果这个Tag完全没有事件侦听,那么就清除这个Tag的侦听{RemoveListen(paramTagID);}}}//移除指定Tag的侦听void RemoveListen(TagID_t paramTagID){gui::Widget * pWidget = GetNodeByTag(paramTagID);if (isNotNULL(pWidget)){pWidget->addTouchEventListener(nullptr, nullptr);}m_Map.RemoveByKey(paramTagID);}private://当UI被侦听的事件,被触发void OnUITouch(CCObject* paramSender, gui::TouchEventType paramType){gui::Widget * pUIControl = dynamic_cast<gui::Widget *>(paramSender);if (isNULL(pUIControl)) return;TagID_t tagID = pUIControl->getTag();STREAM_INFO << "Sender Tag=" << tagID << ", paramType=" << paramType;int iIndex = m_Map.getIndexBykey(tagID);if (m_Map.isValidIndex(iIndex)){auto pV = m_Map.getValue(iIndex);auto pEvent = pV.getByType(paramType);if (isNotNULL(pEvent) && (!pEvent->empty())){(*pEvent)(pUIControl, paramType); //调用事件}}}//取UI中指定Tag的widget对象gui::Widget * GetNodeByTag(TagID_t paramTag){if (isNULL(m_UI)) return nullptr;return m_UI->getWidgetByTag(paramTag);}private:gui::TouchGroup * m_UI;//用Cocostudio UI编辑器,然后导入生成的UI对象TEventMap m_Map;//事件侦听映射表};}#endif

使用例子:在Init函数

m_EventManager = XTouchEventManager::create();m_EventManager->retain();gui::TouchGroup* ul = gui::TouchGroup::create();ul->addWidget(GUIReader::shareReader()->widgetFromJsonFile("MainUI_1.ExportJson"));this->addChild(ul, 2);m_EventManager->setUI(m_MainUI);

最后,事件绑定:

m_EventManager->Bind(ET_BUTTON_EXIT, gui::TOUCH_EVENT_ENDED)->bind(this, &XSceneMain::OnExit);m_EventManager->Bind(ET_BUTTON_SAVE, gui::TOUCH_EVENT_ENDED)->bind(this, &XSceneMain::OnSave);

事件的定义:

void XSceneMain::OnExit(gui::Widget * paramSender, gui::TouchEventType paramType){STREAM_INFO << "OnExit";}        void XSceneMain::OnSave(gui::Widget * paramSender, gui::TouchEventType paramType){STREAM_INFO << "OnSave";}

依赖的代码参考:我的开发代码   

0 0
原创粉丝点击