程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> cocos2d-x學習筆記08:動作1:立即動作

cocos2d-x學習筆記08:動作1:立即動作

編輯:關於C語言

 cocos2d-x學習筆記08:動作1:立即動作


第一部分:動作概述 動作可以說構成了cocos2dx的精華你看動作類有多少子類就知道了)。
動作是什麼?動作可以理解為指令,這些指令由節點執行。
動作由節點node)執行,該節點執行動作的時候,他的所有子節點跟著執行,這一特性是非常有用的。
執行動作的代碼非常簡單,先生成,然後讓節點執行:
  1. CCAction *action=.... 
  2. node->runAction(action); 
 
CCAction及其子類的繼承樹非常龐大,我們需要一個一個介紹。
CCAction及其子類簡圖:
      第二部分:CCActionInstant家族立即動作) 立即動作就是不需要時間,馬上就完成的動作。立即動作的共同基類是CCActionInstant。CCActionInstant的常用子類有:
CCFlipX:X軸翻轉、CCFlipY:Y軸翻轉 CCHide:隱藏、CCShow:顯示、CCToggleVisibility:切換可視性 CCPlace:放置到一個位置 

CCCallFunc家族:回調函數包裝器

 


這些類的使用非常簡單,就不說了
第三部分:CCCallFunc家族回調函數包裝器) CCCallFunc是CCActionInstant的子類,是非常重要的一個類族,就是適配器。用大白話說,就是做了一層包裝,把函數包裝成動作,這樣你在執行動作的時候,就可以執行函數了。聽起來很怪異嗎?為什麼不直接執行函數呢?這是因為執行條件不同。
我們看個例子:玩家死亡動畫也是個動作)播放完成後,結束游戲。(該例子來自於炸彈人,有改動)
  1. CCAction *sequneceAction = CCSequence::actions( 
  2.                         getAnimate(),//獲得死亡動畫,自己實現的函數 
  3.                         CCCallFunc::actionWithTarget(this, callfunc_selector(Hero::deadDoneCallback)),//結束游戲用的回調 
  4.                         NULL); 
  5.  
  6. this->runAction( ); 
  7.  
  8. //回調函數的定義 
  9. void Hero::deadDoneCallback() 
  10.             this->setIsVisible(false);//設置節點隱藏,讓cocos2dx自身清理,而不是馬上清理。 
  11.             CCScene *scene=GameOverScene::scene(); 
  12.             CCDirector::sharedDirector()->replaceScene(CCTransitionFade::transitionWithDuration(1.2f,scene)); 

其他的代碼先不用管它,我們重點是:
  1. CCCallFunc::actionWithTarget(this, callfunc_selector(Hero::deadDoneCallback); 
cocos2dx中,一般對象都是采用靜態方法生成的,我們看這個函數簽名:
  1. static CCCallFunc * actionWithTarget(SelectorProtocol* pSelectorTarget, SEL_CallFunc selector); 
pSelectorTarget是指這個函數的執行對象,這點不要和動作的執行節點搞混,兩者可以是一個也可以不是一個。比如這裡,我用的是this,那麼動作的執行節點和函數的執行對象就是同一個。

  1. void CCCallFunc::execute() { 
  2.             if (m_pCallFunc) { 
  3.                         (m_pSelectorTarget->*m_pCallFunc)(); 
  4.             } 
  5.  
  6.             if (CCScriptEngineManager::sharedScriptEngineManager()->getScriptEngine()) { 
  7.                         CCScriptEngineManager::sharedScriptEngineManager()->getScriptEngine()->executeCallFunc( 
  8.                                                 m_scriptFuncName.c_str()); 
  9.             } 
上面是CCCallFunc::execute()的源碼,m_pSelectorTarget就是之前在簽名裡綁定的pSelectorTarget,而該動作的執行節點則是另外一個變量m_pTarget        

第四部分:使用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. CCAction *a1=CCCallFunc::actionWithTarget(this, callfunc_selector(A::f1)); 
  2. this->runAction(a1); 
  3.  
  4. CCAction *a2=CCCallFuncN::actionWithTarget(this, callfuncN_selector(A::f2)); 
  5. this->runAction(a2); 
  6.  
  7. int i; 
  8. CCAction *a3=CCCallFuncND::actionWithTarget(this, callfuncND_selector(A::f3),(void*)&i); 
  9. this->runAction(a3); 
  10.  
  11. CCObject *obj; 
  12. CCAction *a4=CCCallFuncO::actionWithTarget(this, callfuncO_selector(A::f4),obj); 
  13. this->runAction(a4); 

使用的時候,只需注意類-回調函數-轉換宏,三者之間的對應關系即可,他們都是一一對應的。

 

本文出自 “老G的小屋” 博客,請務必保留此出處http://4137613.blog.51cto.com/4127613/762321

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved