Cocos2d-x v3.x 的事件派发机制(消息处理机制CCNotificationCenter)
来源:互联网 发布:openwrt nginx服务器 编辑:程序博客网 时间:2024/06/05 17:13
1.版本更新
从cocos2d-x v3.0开始,CCNotificationCenter类被抛弃,使用新的事件派发机制:EventDispatcher
2.简介
从cocos2d-x v3.0开始,由于采用了新的C++11的标准,cocos引入了一种新的处理用户事件的事件派发机制。
由三部分组成:
- Event Listener 封装你的事件代码
- Event Dispatcher 通知相应的事件监听器
- Event Object 包含事件的相关信息
为了响应event
,你必须创建一个EventListener
。针对不同类型的event
,共有5种不同的EventListener
:
- EventListenerTouch 触摸事件
- EventListenerKeyboard 按键事件
- EventListenerAcceleration 加速事件
- EventListenerMouse 鼠标事件
- EventListenerCustom 自定义事件
之后,将你的事件处理代码(一般是在callback
函数中)和相应的事件监听器关联起来。例如,onTouchBegin
和EventListenerTouch
相关联、onKeyPressed
和EventListenerKeyboard
相关联。
之后,在EventDispatcher
上注册你的EventListener
。
当事件发生时,EventDispatcher
将会将事件对象Event Object
派发到指定的事件处理回调函数。
3.例子
3.1 TouchEvent
首先,创建3个Sprite
:
auto sprite1 = Sprite::create("Images/CyanSquare.png"); sprite1->setPosition(origin+Point(size.width/2, size.height/2) + Point(-80, 80)); addChild(sprite1, 10); auto sprite2 = Sprite::create("Images/MagentaSquare.png"); sprite2->setPosition(origin+Point(size.width/2, size.height/2)); addChild(sprite2, 20); auto sprite3 = Sprite::create("Images/YellowSquare.png"); sprite3->setPosition(Point(0, 0)); sprite2->addChild(sprite3, 1);
之后,编写EventListener
和相应的回调函数
//Create a "one by one" touch event listener (processes one touch at a time) auto listener1 = EventListenerTouchOneByOne::create(); // When "swallow touches" is true, then returning 'true' from the onTouchBegan method will "swallow" the touch event, preventing other listeners from using it. listener1->setSwallowTouches(true); // Example of using a lambda expression to implement onTouchBegan event callback function listener1->onTouchBegan = [](Touch* touch, Event* event) { // event->getCurrentTarget() returns the *listener's* sceneGraphPriority node. auto target = static_cast<Sprite*>(event->getCurrentTarget()); //Get the position of the current point relative to the button Point locationInNode = target->convertToNodeSpace(touch->getLocation()); Size s = target->getContentSize(); Rect rect = Rect(0, 0, s.width, s.height); //Check the click area if (rect.containsPoint(locationInNode)) { log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y); target->setOpacity(180); return true; } return false; }; //Trigger when moving touch listener1->onTouchMoved = [](Touch* touch, Event* event){ auto target = static_cast<Sprite*>(event->getCurrentTarget()); //Move the position of current button sprite target->setPosition(target->getPosition() + touch->getDelta()); }; //Process the touch end event listener1->onTouchEnded = [=](Touch* touch, Event* event){ auto target = static_cast<Sprite*>(event->getCurrentTarget()); log("sprite onTouchesEnded.. "); target->setOpacity(255); //Reset zOrder and the display sequence will change if (target == sprite2) { sprite1->setZOrder(100); } else if(target == sprite1) { sprite1->setZOrder(0); } };
在EventDispatcher
中注册EventListener
//Add listener _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);
_eventDispatcher
是Node
节点的一个属性,你可以使用它在任意节点中管理事件,例如Scene
,Layer
,Sprite
等等。
上述的例子中,有几个关键的地方需要注意。
1. 在第二次、第三次调用addEventListenerWithSceneGraphPriority
时,我们将listener1
进行了clone
,这是因为一个listener
只能注册一次,
2. FixedPriority
和SceneGraphPriority
FixedPriority
运行你自己设定事件监听器的优先级,值越小,优先级越高。 SceneGraphPriority
则是关联到Node
节点的优先级设计,Node
节点的Z-Index
越高,优先级越高。
3.2自定义事件
触摸、按键事件的事件的触发都是由系统自行管理的,除此之外,你还可以设计自定义的事件触发机制。
_listener = EventListenerCustom::create("game_custom_event1", [=](EventCustom* event){ std::string str("Custom event 1 received, "); char* buf = static_cast<char*>(event->getUserData()); str += buf; str += " times"; statusLabel->setString(str.c_str()); }); _eventDispatcher->addEventListenerWithFixedPriority(_listener, 1);
上面的代码实现了两个功能,一是事件发生后的响应函数,二是在事件派发器中,注册了这个事件响应函数。
那么,这个事件是怎么触发的呢,看下面的代码:
static int count = 0; ++count; char* buf = new char[10]; sprintf(buf, "%d", count); EventCustom event("game_custom_event1"); event.setUserData(buf); _eventDispatcher->dispatchEvent(&event); CC_SAFE_DELETE_ARRAY(buf);
上述的代码中,创建了一个EventCustom
对象,它通过_eventDispatcher->dispatchEvent(&event)
这种方式把事件派发出去。
4. 删除事件监听器EventListener
删除某一个特定的事件监听器:
_eventDispatcher->removeEventListener(listerner);
删除所有监听器
_eventDispatcher->removeAllEventListeners();
注意,在删除了所有监听器之后,menu
也会变为不可用,因为删除了触摸事件监听器,所以,删除所有监听器的操作需要慎重。
- Cocos2d-x v3.x 的事件派发机制(消息处理机制CCNotificationCenter)
- cocos2d-x v3.0 事件派发机制
- cocos2d-x v3.0 事件派发机制
- cocos2d-x v3.0 事件派发机制
- cocos2d-x v3.0 事件派发机制
- cocos2d-x v3.2 触摸事件派发机制
- cocos2d-x v3.0 事件派发机制 注意事项
- cocos2d-x处理点击事件的机制
- [Cocos2d-x v3.x官方文档]事件分发机制
- Cocos2d-x v3.x官方文档: 事件分发机制
- Cocos2d-X研究之v3.x 事件分发机制详解
- cocos2d-x中CCNotificationCenter(消息中心)的应用
- cocos2d-事件派发机制
- Cocos2d-x CCNotificationCenter 通知中心 自定义消息事件
- cocos2d-x Touch事件处理机制
- cocos2d-x Touch事件处理机制
- cocos2d-x Touch事件处理机制
- cocos2d-x Touch事件处理机制
- Android View滑动
- 图片的二进制数据库存储和显示
- Spring MVC 4 学习5: 配置数据源(proxool连接池)及使用例子
- error: format not a string literal and no format arguments
- js操作select option
- Cocos2d-x v3.x 的事件派发机制(消息处理机制CCNotificationCenter)
- window 下修改mysql 数据库的密码
- Java变量以及内存分配
- 内存泄露的解释
- Flex 布局教程:语法篇
- JAVA并发处理经验(四)并行模式与算法6:NIO网络编程
- ueditor
- git与tortoisegit结合使用openSSH与PuTTY
- Android和PC间的通信