专职C++

不能停止的脚步

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  143 Posts :: 7 Stories :: 134 Comments :: 0 Trackbacks

常用链接

留言簿(13)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

60天内阅读排行

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::map
        typedef XMap<TagID_t, STagEvent> TEventMap;
    public:
        XTouchEventManager()
            :m_UI(nullptr)
        {}

        static XTouchEventManager * create()
        {
            XTouchEventManager * pRet = new XTouchEventManager();
            pRet->autorelease();
            return pRet;
        }
        //property
        void 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";  
}  

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

posted on 2014-07-15 15:58 冬瓜 阅读(2312) 评论(0)  编辑 收藏 引用 所属分类: 原创cocos2dx

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理