cocos2d-x3.0事件处理机制

本文深入解析cocos2d-x3.0版本中事件处理机制的变化,特别是回调接口的更新以及触摸机制的优化。详细介绍了CC_CALLBACK的使用方式,包括在3.0版本中替代旧有回调函数的四个CC_CALLBACK的差别,并通过实例展示了如何使用Callfunc简化动作回调的编写。同时,文章对比了单点触摸与多点触摸的实现方式,强调了触摸优先级的概念,并提供了设置触摸监听优先级的方法。最后,通过实例说明了如何利用克隆监听器实现多个精灵的触摸功能。此外,还介绍了删除触摸监听的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值