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