cocos2d-x3.0事件處理機制

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章