[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";
}
依赖的代码參考:我的开发代码
[cocos2dx笔记010]用于UI的事件管理器的更多相关文章
- phalcon:model 事件与事件管理器
事件与事件管理器(Events and Events Manager)¶ Models allow you to implement events that will be thrown when p ...
- storm事件管理器EventManager源码分析-event.clj
storm事件管理器定义在event.clj中,主要功能就是通过独立线程执行"事件处理函数".我们可以将"事件处理函数"添加到EventManager的阻塞队列 ...
- cocos2d-js v3事件管理器
总概: 1.时间监听器(cc.EventListener)封装用户的事件处理逻辑. 2.事件管理器(cc.eventManager)管理用户注册的事件监听器. 3.事件对象(cc.Event)包含事件 ...
- 【Python学习笔记】with语句与上下文管理器
with语句 上下文管理器 contextlib模块 参考引用 with语句 with语句时在Python2.6中出现的新语句.在Python2.6以前,要正确的处理涉及到异常的资源管理时,需要使用t ...
- Win 7 通过事件管理器查看计算机开机关机时间
控制面板-管理工具-事件查看器 视图中开机来源:Kernel-General 事件ID:13 关机来源:Kernel-General 事件ID:12
- 安卓开发:UI组件-布局管理器和文本显示
接下来的随笔,记录了在学习b站up主:天哥在奔跑,录制的教学视频的同时,进行一个app开发. up主:天哥在奔跑 视频地址:https://www.bilibili.com/video/av38409 ...
- Openresty 学习笔记(四)lualocks包管理器安装使用
Luarocks是一个Lua包管理器,基于Lua语言开发,提供一个命令行的方式来管理Lua包依赖.安装第三方Lua包等,社区比较流行的包管理器之一,另还有一个LuaDist,Luarocks的包数量比 ...
- JMeter学习笔记(四) HTTP Cookies 管理器
有些接口执行时,要求要先登录,此时就需要用到 HTTP Cookies 管理器.不过有些项目是使用的token,即添加HTTP信息头管理器,获取登录后的token,至于token与cookies的区别 ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
随机推荐
- 用C++/CLI搭建C++和C#之间的桥梁(三)—— 基本类型
数值类型 对于基本的数值类型,在C++/CLI中是可以直接映射为托管类型的数值的,可以同时应用于托管类型和非托管类型,编译器会将其自动转换. 基本类型 System命名空间中对应的类 注释/用法 bo ...
- LT3759 宽输入电压范围升压 / 负输出 / SEPIC 控制器 可在输入电压低至 1.6V 的情况下工作
引言当今的许多电子设备都需要一个负输出或正输出转换器,有时则是两者均需要.另外,它们还必需采用各种电源运作,包括 USB.墙上适配器.碱性电池和锂电池等. 为了从可变输入电压产生不同极性的输出,电源设 ...
- js继承——从创建对象开始
从创建对象开始 创建对象的简单方法就是:使用Object构造函数或者对象字面量.但这两个方法有个缺点:创建相同对象,要编写大量重复代码. 为了避免这个问题——>工厂模式:用函数封装以特定接口创建 ...
- C#中有关资源、BeginInvoke, Invoke和事件的事情
事情是这么来的,我开发的一个程序报了一个错误 “在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke错误”. 然后我在网上查资料,发现一个有意思的问题,文章出处为“在创建窗口 ...
- IOS批量截取视频截图 UIImage mp4 IOS Video
IOS批量截取视频截图 //生成截图 NSString *path = [NSHomeDirectory() stringByAppendingString:@"/Documents&quo ...
- 3)Linux程序设计入门--文件操作
)Linux程序设计入门--文件操作 Linux下文件的操作 前言: 我们在这一节将要讨论linux下文件操作的各个函数. 文件的创建和读写 文件的各个属性 目录文件的操作 管道文件 .文件的创建和读 ...
- Sql server left join,right join和inner join的比较
转载于:http://www.2cto.com/database/201206/137067.html Sql server left join,right join和inner join的比较 ...
- ubuntu14.04如何卸载mysql
1. 删除mysql的数据文件 sudo rm /var/lib/mysql/ -R 2. 删除mqsql的配置文件 sudo rm /etc/mysql/ -R 3. 自动卸载mysql的程序 su ...
- PHP curl 抓取AJAX异步内容
其实抓ajax异步内容的页面和抓普通的页面区别不大.ajax只不过是做了一次异步的http请求,只要使用firebug类似的工具,找到请求的后端服务url和传值的参数,然后对该url传递参数进行抓取即 ...
- RS导出Excel交叉表角对应的列占用多列问题
在Cognos报表展示的时候,很多用户为了计算会把数据报表导出成excel然后再做统计,于是乎我做的一张报表导出成Excel的时候就出现了这样的问题 从上图可以看出交叉表角对应的列 ‘一级手术’和‘二 ...