1. 程式人生 > >Cocos2dx中常用回撥函式解析

Cocos2dx中常用回撥函式解析

先來看回調函式的定義:

class Node;

typedef void (Ref::*SEL_CallFunc)();
typedef void (Ref::*SEL_CallFuncN)(Node*);
typedef void (Ref::*SEL_CallFuncND)(Node*, void*);
typedef void (Ref::*SEL_CallFuncO)(Ref*);
typedef void (Ref::*SEL_MenuHandler)(Ref*);
typedef void (Ref::*SEL_SCHEDULE)(float);

#define CC_CALLFUNC_SELECTOR
(_SELECTOR) static_cast<cocos2d::SEL_CallFunc>(&_SELECTOR) #define CC_CALLFUNCN_SELECTOR(_SELECTOR) static_cast<cocos2d::SEL_CallFuncN>(&_SELECTOR) #define CC_CALLFUNCND_SELECTOR(_SELECTOR) static_cast<cocos2d::SEL_CallFuncND>(&_SELECTOR) #define CC_CALLFUNCO_SELECTOR(_SELECTOR
)
static_cast<cocos2d::SEL_CallFuncO>(&_SELECTOR) #define CC_MENU_SELECTOR(_SELECTOR) static_cast<cocos2d::SEL_MenuHandler>(&_SELECTOR) #define CC_SCHEDULE_SELECTOR(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR) // Deprecated #define callfunc_selector(_SELECTOR
)
CC_CALLFUNC_SELECTOR(_SELECTOR) #define callfuncN_selector(_SELECTOR) CC_CALLFUNCN_SELECTOR(_SELECTOR) #define callfuncND_selector(_SELECTOR) CC_CALLFUNCND_SELECTOR(_SELECTOR) #define callfuncO_selector(_SELECTOR) CC_CALLFUNCO_SELECTOR(_SELECTOR) #define menu_selector(_SELECTOR) CC_MENU_SELECTOR(_SELECTOR) #define schedule_selector(_SELECTOR) CC_SCHEDULE_SELECTOR(_SELECTOR)

typedef: 定義一種型別的別名, typedef void (*fff)(float) 表示fff是一個函式,這個函式的返回型別是 void ,只有一個 float 型別的引數。
#define: 只是一個加單的字串替代巨集,#define A B 的意思是:A和B是一樣的東西,只不過換了個寫法,經常用在:用一個簡單的字串代替一串複雜的字串、用一些有意義的單詞組合來代表某些值。

schedule 家族

scheduleUpdate:通過this->scheduleUpdate()把定時器加到節點後,節點會每幀都會呼叫虛擬函式:update(void);
取消方法:this->unscheduleUpdate(); 只能觸發虛擬函式 update()

schedule:定義是 void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
通過this->schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay) 把定時器加到節點,可以指定回撥函式、觸發間隔、重複次數、延遲啟動時間,第二個引數(觸發間隔)為0則表示每幀都觸發,相當於scheduleUpdate,但優勢在於可以自己指定回撥方法;
取消方法:this->unschedule(SEL_SCHEDULE selector);

scheduleOnce: 定義是 void CCNode::scheduleOnce(SEL_SCHEDULE selector, float delay);
this->scheduleOnce(selector, delay) 把定時器加到節點,指定回撥函式和延遲啟動時間,只會觸發一次。
取消方法:this->unscheduleOnce(selector);

callFunc 家族

當我們需要在一個動作序列中某一個動作執行結束之後,呼叫某個函式用於執行一個任務的時候,我們可以使用CCCallFunC家族函式。CCCallFunC是CCActionInstant類的子類。值得注意的是,雖然CCCallFunC家族函式是瞬時動作函式的子類,但是所謂的瞬時,也只是指函式呼叫的一瞬間,而關於函式內部怎麼執行,耗用多久,則完全與瞬時沒有任何關係。CCCallFunC家族函式可以將函式呼叫的過程封裝成一個動作類,從而放入動作序列中以供我們呼叫。
下面通過例項來說明callFunc的具體使用:

標頭檔案:

#include "cocos2d.h"
class HelloWorld : public cocos2d::CCLayerColor
{
public:
    virtual bool init();

    static cocos2d::CCScene* scene();

    //先宣告四個動作的回撥方發
    void callBack();
    void callNodeBack(CCNode* sender);
    void callNodeBack(cocos2d::CCNode *sender, void * data);
    void callObjectBack( CCObject * data);
    // preprocessor macro for "static create()" constructor ( node() deprecated )
    CREATE_FUNC(HelloWorld);
};
#endif // __HELLOWORLD_SCENE_H__

原始檔init函式如下:

bool HelloWorld::init()
{
    if ( !CCLayerColor::initWithColor(ccc4(255, 255, 255, 255)) )
   {
       return false;
   }

   //CCCallFunc家族函式:當我們需要在一個動作完成之後需要呼叫某個函式時使用

   CCSprite* player = CCSprite::create("Icon.png");
   player->setPosition(ccp(100, 100));
   this->addChild(player);
   CCMoveTo* action = CCMoveTo::create(1, ccp(200, 200));
}
//CCCallFunc的功能非常簡單,它只能簡單地實現在動作序列中幫助我們呼叫一個函式的功能。
   CCCallFunc* call  = CCCallFunc::create(this, callfunc_selector(HelloWorld::callBack));
   //下面這行程式碼是建立一個動作序列
   CCFiniteTimeAction* seq = CCSequence::create(action,call,NULL);
   player->runAction(seq);
void HelloWorld::callBack()
{
    CCLog("CCCallFunc");
}
//CCCallFuncN  既能夠呼叫一個方法還能夠將呼叫的物件傳過去  這裡的呼叫物件就是player  它是個精靈物件
    CCCallFuncN* callN = CCCallFuncN::create(this, callfuncN_selector(HelloWorld::callNodeBack));
    CCFiniteTimeAction* seq2 = CCSequence::create(action,callN,NULL);
    player->runAction(seq2);
//CCCallFuncN的回撥函式
void HelloWorld::callNodeBack(cocos2d::CCNode *sender)
{
    CCSprite* player = (CCSprite*) sender;
    CCLog("%f",player->getPosition().x);
}
//先建立一個字典
    CCDictionary* dic = CCDictionary::create();
    dic->retain();
    dic->setObject(CCString::create("zxcc"), 1);

    //CCCallFuncND可以傳遞一個任意資料型別  例如,我們可以傳遞一個字典
    CCCallFuncND* callND = CCCallFuncND::create(this, callfuncND_selector(HelloWorld::callNodeBack),(void*)dic);
    CCFiniteTimeAction* seq3 = CCSequence::create(action,callND,NULL);
    player->runAction(seq3);
//CCCallFuncND的回撥函式
void HelloWorld::callNodeBack(cocos2d::CCNode *sender, void * data)
{
    CCDictionary* dic = (CCDictionary*)data;
    CCString* str = (CCString*)(dic->objectForKey(1));

      CCLog("%s",str->getCString());
}
//我們建立一個精靈
    CCSprite* player2 = CCSprite::create("player2.png");
    player2->setPosition(ccp(300, 300));
    this->addChild(player2);
    //在例子中我先移動一個精靈 ,再移動另一個精靈
   // CCCallFuncO傳值的型別只能為CCObject型別
    CCCallFuncO* callO = CCCallFuncO::create(this, callfuncO_selector(HelloWorld::callObjectBack), player2);
    CCFiniteTimeAction* seq4 = CCSequence::create(action,callO,NULL);
    player->runAction(seq4);
//CCCallFuncO的回撥方法
void HelloWorld::callObjectBack(cocos2d::CCObject *data)
{
    CCSprite* player = (CCSprite*)data;

    player->runAction(CCMoveTo::create(1, ccp(1 ,90)));

}