cocos2d-x3.0事件处理机制

来源:互联网 发布:朱迪斯巴特勒 知乎 编辑:程序博客网 时间:2024/05/03 19:33

cocos2d-x3.0事件处理机制

事件回调

3.0 后的事件回调函数接口都不一样了,例如按钮的menu_selector(),update的 schedule_selector等,都已成明日黄花。而新的回调接口,则由四个CC_CALLBACK取代。

其实CC_CALLBACK的差别就在于后面的数字啦,0就代表回调的是没有参数的函数,1就是有一个参数,2 就是有两个参数。

 

3.0里Callfunc的新的用法

auto action1 = CallFunc::create(                [&](){                    auto s =Director::sharedDirector()->getWinSize();                    auto label =LabelTTF::create("called:lambda callback", "Marker Felt", 16);                    label->setPosition(ccp(s.width/4*1,s.height/2-40));                    this->addChild(label);                }  );

以前动作回调都是要新写一个回调函数,这样子虽然问题不大,但如果用到回调的地方多了,而且回调的代码也就几行而已,那之前的做法就有点受不了,现在好了,可以直接把动作执行完要回调的函数代码直接写到创建里来,是不是方便多了。


触摸机制

一、单点触摸:

方法1

声明:

bool onTouchBegan(Touch* touch, Event  *event);void onTouchMoved(Touch* touch, Event  *event);void onTouchEnded(Touch* touch, Event  *event);

实现:

写在init方法中

auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(false);listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan, this);listener->onTouchMoved = CC_CALLBACK_2(MainLayer::onTouchMoved,this);listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

bool MainLayer::onTouchBegan(Touch* touch, Event  *event){}void MainLayer::onTouchMoved(Touch* touch, Event  *event){}void MainLayer::onTouchEnded(Touch* touch, Event  *event){  }

方法2

实现:

写在init方法中

auto listener1 = EventListenerTouchOneByOne::create();listener1->setSwallowTouches(false);listener1->onTouchBegan = [ ](Touch* touch, Event* event){};listener1->onTouchMoved = [ ](Touch* touch, Event* event){};listener1->onTouchEnded = [=](Touch* touch, Event* event){};_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);

二、多点触摸:

声明:

void onTouchesBegan(const std::vector<Touch*>& touches, Event  *event);void onTouchesMoved(const std::vector<Touch*>& touches, Event  *event);void onTouchesEnded(const std::vector<Touch*>& touches, Event  *event);

实现:

写在init方法里

auto listener = EventListenerTouchAllAtOnce::create();listener->onTouchesBegan = CC_CALLBACK_2(OptionLayer::onTouchesBegan, this);listener->onTouchesMoved = CC_CALLBACK_2(OptionLayer::onTouchesMoved, this);listener->onTouchesEnded = CC_CALLBACK_2(OptionLayer::onTouchesEnded, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

void OptionLayer::onTouchesBegan(const std::vector<Touch*>& touches, Event  *event){}void OptionLayer::onTouchesMoved(const std::vector<Touch*>& touches, Event  *event){}void OptionLayer::onTouchesEnded(const std::vector<Touch*>& touches, Event  *event){}


触摸机制还有个不同的地方,只要是放在最上面的那个精灵,那它的触摸优先级就最高。我们用的按钮Menu 就是用这种方式设置触摸优先级的。

将listener1添加到事件调度中,这里用的是:

_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1 sprite);  

我们进入addEventListenerWithSceneGraphPriority的定义中看一下,有下面这一行代码:

listener->setFixedPriority(0);  

它将精灵的触摸优先级设置成0,从这里我们可以引申出两个问题,一个就是当我们要给精灵设置触摸优先级时,

listener->setFixedPriority(0);  

,因为0已经被“官府”征用了,另一个问题就是:如果自己想设置精灵的触摸优先级,那应该怎么做呢?下面是提供的另外一种添加listener的方法:

_eventDispatcher->addEventListenerWithFixedPriority(listener1 ,fixedPriority);  

在第二个参数里设置触摸优先级,这样就可以了。


如果你有多个精灵sprite,且这些精灵都想实现拖动的功能,那么这些精灵都可以使用listener1这一个触摸监听,例如我们有三个精灵,sprite,sprite2,sprite3,他们调用listener1的方式:

 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);   _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);  _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);  

其中sprite2和sprite3都是克隆了listener1的,进入clone()的定义,我们看到以下代码:

EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone()  {      auto ret = new EventListenerTouchOneByOne();      if (ret && ret->init())      {          ret->autorelease();                    ret->onTouchBegan = onTouchBegan;          ret->onTouchMoved = onTouchMoved;          ret->onTouchEnded = onTouchEnded;          ret->onTouchCancelled = onTouchCancelled;                    ret->_claimedTouches = _claimedTouches;          ret->_needSwallow = _needSwallow;      }      else      {          CC_SAFE_DELETE(ret);      }      return ret;  }  

以上代码主要的目的也就是实现克隆touchbegan,touchmoved,touchended。

删除触摸监听

_eventDispatcher->removeEventListeners(EventListener::Type::TOUCH_ONE_BY_ONE);  

这样就OK了。


0 0