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了。