cocos2d-x學習筆記 動作 CCCallFunc家族(回調函數包裝器)

  CCCallFuncCCActionInstant的子類,是非常重要的一個類族,就是適配器。用大白話說,就是做了一層包裝,把函數包裝成動作,這樣你在執行動作的時候,就可以執行函數了。聽起來很怪異嗎?爲什麼不直接執行函數呢?這是因爲執行條件不同。

 

 

 使用CCCallFunc家族的類

CCCallFunc家族一共有四個類。這是四個類對象的靜態生成函數:

1. CCCallFunc * CCCallFunc::actionWithTarget(SelectorProtocol* pSelectorTarget,SEL_CallFunc selector); 

2. CCCallFuncN * CCCallFuncN::actionWithTarget(SelectorProtocol* pSelectorTarget,SEL_CallFuncN selector); 

3. CCCallFuncND * CCCallFuncND::actionWithTarget(SelectorProtocol* pSelectorTarget,SEL_CallFuncND selector, void* d); 

4. CCCallFuncO * CCCallFuncO::actionWithTarget(SelectorProtocol* pSelectorTarget,SEL_CallFuncO selector, CCObject* pObject) 

我們在寫的時候,就直接用這四個生成相關的動作對象,然後讓節點執行就行。

 

 

 

但是要注意這四個類,分別對應的是四種不同的函數接口,也可以說是他包裝了四種不同的回調函數。這四個回調函數的不同主要是參數表的不同。(貌似是廢話)我們來看這四個回調函數的類型定義

1. typedef void (SelectorProtocol::*SEL_CallFunc)(); 

2. typedef void (SelectorProtocol::*SEL_CallFuncN)(CCNode*); 

3. typedef void (SelectorProtocol::*SEL_CallFuncND)(CCNode*, void*); 

4. typedef void (SelectorProtocol::*SEL_CallFuncO)(CCObject*); 

這四個玩意要解釋清楚比較麻煩,這是用typedef定義了類成員函數指針。如果你對C++不熟悉,你不需要搞懂具體什麼意思,但你必須保證你的函數簽名和這四個其中之一一致。

 

也就是說,你自己寫的回調函數簽名,看起來像這樣:

1. void A::f1( ); 

2. void A::f2(CCNode *node);//接受一個節點,該節點是動作的執行節點 

3. void A::f3(CCNode *node,void *param);//接受動作的執行節點,還有一個void參數 

4. void A::f4(CCObject* obj);//接受一個CCObject對象指針 

你可以在回調函數裏操作這些被傳進來的參數。

 

另外,在用靜態函數生成動作的時候,你需要使用一個宏,來幫助轉換函數指針類型,就是上面那個callfunc_selector,因爲有四種類型的回調函數,所以也就有四個類型轉換宏

1. #define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR) 

2. #define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR) 

3. #define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR) 

4. #define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR) 

下面寫一個實例供參考:

  1. void Enemy::boxAttacked(Direction dir,Behaviour be,int i) 
  2.     behaviour=be; 
  3.     direction=dir; 
  4.      
  5.  
  6.     this->cleanup(); 
  7.     sprite->cleanup(); 
  8.     CCAction *sequneceAction = CCSequence::actions( 
  9.         getAnimate("box"), 
  10.         CCCallFuncND::actionWithTarget(this, callfuncND_selector(Enemy::boxAttackedDone),(void*)i), 
  11.         NULL); 
  12.      
  13.     sprite->runAction(sequneceAction); 
  14. void Enemy::boxAttackedDone(CCNode* pSender,void* i) 
  15.     int j=(int)i; 
  16.  
  17.  
  18.     if(j==1) 
  19.     { 
  20.         behaviour=MOVE; 
  21.         direction=BONE; 
  22.     } 
  23.     else if(j==2) 
  24.     { 
  25.         behaviour=MOVE; 
  26.         direction=BTWO; 
  27.     } 
  28.     else if(j==3) 
  29.     { 
  30.         behaviour=MOVE; 
  31.         direction=BTHREE; 
  32.     } 
  33.      
  34.     sprite->stopAllActions(); 
  35.     sprite->runAction(CCRepeatForever::actionWithAction(getAnimate("box"))); 
  36.      

 

 

 

 

 

 

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