zoukankan      html  css  js  c++  java
  • [cocos2dx笔记010]用于UI的事件管理器

    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";
    	}
    

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

  • 相关阅读:
    char
    export和export default
    递归打印文件目录
    centso7 安装redmine
    sonar结合jenkins
    sonar安装
    gitlab+jenkins
    centos5 安装redmine
    elk安装最佳实践
    elk认证模块x-pack安装
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7293951.html
Copyright © 2011-2022 走看看