Cocos游戏当中产生一个事件时,可以有多个对象在监听该事件,所以有优先级(Priority).优先级越高(Priority值越小),事件响应越靠前。
关系图:
新 事件分发机制:在2.x 版本事件处理时,将要触发的事件交给代理(delegate)处理,再通过实现代理里面的onTouchBegan等方法接收事件,最后完成事件的响应。 而在新的事件分发机制(3.x)中,只需通过创建一个事件监听器-用来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher,所 有事件监听器由这个分发器统一管理,即可完成事件响应。
事件监听器有以下几种:
- 触摸事件 (EventListenerTouch)
- 键盘响应事件 (EventListenerKeyboard)
- 鼠标响应事件 (EventListenerMouse)
- 自定义事件 (EventListenerCustom)
- 加速记录事件 (EventListenerAcceleration)
_eventDispatcher的工作由三部分组成:
- 事件分发器 EventDispatcher
- 事件类型 EventTouch, EventKeyboard 等
- 事件监听器 EventListenerTouch, EventListenerKeyboard 等
监听器实现了各种触发后的逻辑,在适当时候由事件分发器分发事件类型,然后调用相应类型的监听器。
一.触摸事件
单点触摸:
1 bool HelloWorld::init() 2 { 3 ////////////////////////////// 4 // 1. super init first 5 if ( !Layer::init() ) 6 { 7 return false; 8 } 9 Size visibleSize = Director::getInstance()->getVisibleSize(); 10 11 /* 创建精灵 */ 12 Sprite* sp1 = Sprite::create("sprite1.png"); 13 sp1->setPosition(Point(visibleSize.width * 0.5f, visibleSize.height * 0.5f)); 14 this->addChild(sp1); 15 16 //注册监听 17 auto listener = EventListenerTouchOneByOne::create(); 18 listener->setSwallowTouches(true); //阻止向下传递 19 listener->onTouchBegan = [](Touch* touch, Event* event){ 20 /* 获取事件绑定的精灵 */ 21 auto target = static_cast<Sprite*>(event->getCurrentTarget()); 22 Point pos = Director::getInstance()->convertToGL(touch->getLocationInView()); 23 24 /* 检测是否触摸到精灵 ⁄ */ 25 if (target->getBoundingBox().containsPoint(pos)) 26 { 27 /* 设置这个绑定到的精灵的透明度 */ 28 target->setOpacity(100); 29 30 return true; 31 } 32 33 return false; 34 }; 35 listener->onTouchMoved =[=](Touch* touch,Event* event) 36 { 37 /* 拖着精灵走 */ 38 auto target = static_cast<Sprite*>(event->getCurrentTarget()); 39 target->setPosition(touch->getLocation()); 40 }; 41 42 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sp1); 43 44 45 return true; 46 }
效果图:
多点触摸:
1 #include "cocos2d.h" 2 USING_NS_CC; 3 class HelloWorld : public cocos2d::Layer 4 { 5 public: 6 7 static cocos2d::Scene* createScene(); 8 9 virtual bool init(); 10 11 void onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event); 12 13 void onTouchesMoved(const std::vector<Touch*>& touches, Event *unused_event);
1 // on "init" you need to initialize your instance 2 bool HelloWorld::init() 3 { 4 ////////////////////////////// 5 // 1. super init first 6 if ( !Layer::init() ) 7 { 8 return false; 9 } 10 Size visibleSize = Director::getInstance()->getVisibleSize(); 11 12 /* 创建精灵 */ 13 Sprite* sp1 = Sprite::create("HelloWorld.png"); 14 sp1->setPosition(Point(visibleSize.width * 0.5f, visibleSize.height * 0.5f)); 15 this->addChild(sp1); 16 17 //注册监听 18 auto listener = EventListenerTouchAllAtOnce::create(); 19 listener->onTouchesBegan =CC_CALLBACK_2(HelloWorld::onTouchesBegan, this); 20 listener->onTouchesMoved =CC_CALLBACK_2(HelloWorld::onTouchesMoved, this); 21 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sp1); 22 23 24 return true; 25 } 26 27 //多点触摸事件响应函数 28 void HelloWorld::onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event) { CCLOG("began"); } 29 30 void HelloWorld::onTouchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event) 31 { 32 auto sprite =static_cast<Sprite*>(event->getCurrentTarget()); 33 //缩放 34 if(touches.size() > 1) 35 { 36 auto distance1 = touches[0]->getPreviousLocation().distance(touches[1]->getPreviousLocation()); 37 auto distance2 = touches[0]->getLocation().distance(touches[1]->getLocation()); 38 39 float scale = sprite->getScale() * ( distance2 / distance1); 40 scale = MIN(2,MAX(0.5, scale)); 41 42 sprite->setScale(scale); 43 } 44 else 45 { 46 log("单点"); 47 } 48 }
由于多点触摸缩放扩大不方便放示例图出来。大家写好代码Run到真机测试一下。本示例已测试,绝对ok。
OK关于这一章的触摸事件就分享至此,关于事件的加速计等教程会放在基础教程来讲。下一章将讲述Cocos各种专业名词。之后将跨越入门这道栏。进入中级开发。