cocos2d-x學習筆記——cocos2d-x3.0回撥函式的變化
在cocos2d-x 2.x版本中的回撥函式的用法想必大家都很是熟悉,例如在menu item,call back action中都需要大量的使用到回撥函式,但是在使用過程中總是感覺到比較冗餘麻煩的,在3.0版本,使用到了C++11 的新特性,改進增加了回到函式的使用形式,其中最令人欣慰的是,可以使用閉包,對於有過iOS開發經驗的來說,應該很親切,就是 block。
下面將通過幾個例子詳細介紹在3.0版本中回撥函式的各種用法。溫馨提示:由於用到了C++11中的std::function,std::bind和lambda表示式,所以對此不太瞭解的可以先看看我之前的這篇有關C++11的一些用法介紹
一、通過 HelloWorldScene 中的 closeItem 開始
在cocos2d-x 2.x 版本中:
- CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
- "CloseNormal.png",
- "CloseSelected.png",
-
this
- menu_selector(HelloWorld::menuCloseCallback));
在cocos2d-x 3.0 版本中:
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png",
-
"CloseSelected.png"
- CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
- void HelloWorld::menuCloseCallback(Object* pSender)
- {
- Director::getInstance()->end();
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- exit(0);
- #endif
- }
注意到在3.0版本中使用到 CC_CALLBACK_1 這樣一個巨集定義。
- // new callbacks based on C++11
- #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
- #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
- #define CC_CALCC_CALLBACK_1(HelloWorld::menuCloseCallback,this)LBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
- #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 ##__VA_ARGS__)
原來還有 CC_CALLBACK_0 1 2 3;而其中又有什麼區別呢?
1、首先我們看看3.0版本中MenuItemImage的create方法:
- MenuItemImage * MenuItemImage::create(const std::string& normalImage, const std::string& selectedImage, const ccMenuCallback& callback)
- typedef std::function<void(Object*)> ccMenuCallback
注意到 在 CC_CALLBACK_ 的巨集定義的中使用到的是 C++ 的 bind 語法,怎麼不一致了呢? -- 見下面第四點 function
2、看回 CC_CALLBACK_ 的巨集定義
原來 CC_CALLBACK_ 的巨集定義中後面的 0 1 2 3分別表示的是 不事先指定回撥函式引數的個數。
例如說 CC_CALLBACK_ 1 表示的是,回撥函式中不事先指定引數是一個,而事先指定的回撥函式的引數 可以任意多個。
而且要注意到其中 不指定回撥函式引數 和 指定回撥函式引數 的順序,注意不事先指定的在前,事先指定的在後。
下面通過例子說明這一點:
假設回撥函式:
- // a selector callback
- void menuCloseCallback(Object* pSender,int a,int b);
- void HelloWorld::menuCloseCallback(Object* pSender,int a,int b)
- {
- std::cout<<a<<" "<<b<<std::endl;
- Director::getInstance()->end();
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- exit(0);
- #endif
- }
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png",
- "CloseSelected.png",
- CC_CALLBACK_1(HelloWorld::menuCloseCallback,this,1,2));
執行,在 點選closeItem 的時候,就會輸出這兩個事先指定的引數 1 2。
那麼,不事先指定的引數是在什麼時候傳入的呢?
- void MenuItem::activate()
- {
- if (_enabled)
- {
- if( _callback )
- {
- _callback(this);
- }
- if (kScriptTypeNone != _scriptType)
- {
- BasicScriptData data(this);
- ScriptEvent scriptEvent(kMenuClickedEvent,&data);
- ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent);
- }
- }
- }
這樣,closeItem 的回撥函式的 void HelloWorld::menuCloseCallback(Object* pSender,int a,int b) 的三個引數都知道了。
第一個 不事先指定,在menu item呼叫 activate 的時候,_callback(this) 傳入,this 也即是這個 menu item;第二、三個引數是事先指定的 1,2。
3、bind
已經知道 CC_CALLBACK_ 的巨集定義是 std::bind 那麼我們可以直接使用std::bind。
如下:
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png",
- "CloseSelected.png",
- std::bind(&HelloWorld::menuCloseCallback, this,std::placeholders::_1,1,2));
4、function
最後就解決上面的一個疑惑。
- std::function<void(Object*)> func = std::bind(&HelloWorld::menuCloseCallback,this, std::placeholders::_1,1,2);
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png",
- "CloseSelected.png",
- func);
5、使用lambda表示式
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png",
- "CloseSelected.png",
- [&](Object *sender){
- Director::getInstance()->end();
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- exit(0);
- #endif
- });
二、在cocos2d-x中,還有一個地方是需要大量使用到回撥函式的,這就是回撥動作:CCCallFunc、CCCallFuncN、CCCallFuncND、CCCallFuncO。
但是這四個回撥動作在 3.0 版本中已經都提示 deprecate 了。那麼在3.0 版本中已經只剩下 CallFunc 和 CallFuncN.
下面是官方文件中的說明:
CallFunc
can be created with anstd::function<void()>
CallFuncN
can be created with anstd::function<void(Node*)>
CallFuncND
andCallFuncO
were removed since it can be created with simulated withCallFuncN
andCallFunc
. See ActionsTest.cpp for more examples
下面通過例子詳細的介紹這兩個回撥動作的用法。
1、CallFunc
- static CallFunc * create(const std::function<void()>& func);
關於CallFunc的例子,在文件中已經有體現:
- // in v2.1
- CCCallFunc *action1 = CCCallFunc::create( this, callfunc_selector( MyClass::callback_0 ) );
- // in v3.0 (short version)
- auto action1 = CallFunc::create( CC_CALLBACK_0(MyClass::callback_0,this));
- auto action2 = CallFunc::create( CC_CALLBACK_0(MyClass::callback_1,this, additional_parameters));
- // in v3.0 (long version)
- auto action1 = CallFunc::create( std::bind( &MyClass::callback_0, this));
-
auto action2 = CallFunc::create( std::bind( &MyClass::callback_1, this
相關推薦
cocos2d-x學習筆記——cocos2d-x3.0回撥函式的變化
在cocos2d-x 2.x版本中的回撥函式的用法想必大家都很是熟悉,例如在menu item,call back action中都需要大量的使用到回撥函式,但是在使用過程中總是感覺到比較冗餘麻煩的,在3.0版本,使用到了C++11 的新特性,改進增加了回
【cocos2d-x從c++到js】回撥函式1——按鍵回撥
回撥函式是介面互動和接入各種第三方SDK的關鍵所在,因為回撥函式的C++程式碼是不能自動生成的,一切的一切,都需要手寫完成。 比較不錯的是,Cocos2d-x引擎對於回撥函式提供了完整的包裝機制。我們所需要做的就是了解這個機制,並使用他。學習引擎自己的程式碼
Nodejs學習筆記 day02——REPL和回撥函式
1、REPL(互動式直譯器): Node自帶互動式直譯器: 讀取使用者輸入 ==> 執行輸入的資料結構 ==> 列印輸出結果(迴圈執行,直到使用者按ctrl+c兩下後結束) 變數: var x = 10 //宣告變數並賦值,如果沒有
cocos2d-x學習筆記(c++與lua交互回調函數的處理)
回調函數 tolua++ cocos2dx lua 本文假設讀者已經會使用tolua++進行C++與lua之間的通訊1、在頭文件中定義註冊回調函數,定義在MyClass類中void register(unsigned short cmdID, LUA_FUNCTION func);//LUA_
Cocos2d-x學習筆記(四) 布景層的加入移除
dcl from position 顏色 顯示地圖 idt col 分享 學習 布景層類也就是CCLayer類,每一個遊戲場景中都能夠有非常多層,每一層負責各自的任務。顯示地圖、顯示人物等。同一時候層還是一個容器,能夠放入文本、圖片和菜單。構成遊戲中一個個UI。這次
cocos2d-x學習筆記(十二)cocos2dx 3.10添加lua LuaFileSystem庫遍歷文件
luafilesystem庫;lfs;遍歷文件在lua中遍歷目錄文件需要用到lfs庫,而所用的cocos2dx 3.10沒用lfs,需要自己添加1、下載lfs.c和lfs.hhttps://github.com/keplerproject/luafilesystem 從github獲取源碼,在src目錄拷貝l
Cocos2d-x學習筆記(十)例項——記住帳號(密碼)功能
【關於記住賬號/密碼】 在很多需要賬號、密碼驗證的應用程式,“記住密碼”是非常常見的,那麼如何用cocos2d-x來實現呢?這裡用選單來實現“記住密碼”的功能。 【記住賬號/密碼的實現】 (1)首先準備兩張圖片,即選單項兩種狀態(正常和點選)下顯示的的圖片背景,以便在使用者多次
Cocos2d-x學習筆記(九)例項——場景自動切換
【關於場景自動切換】 如何實現場景的自動切換?我嘗試過很多種方法,比如在AppDelegate.cpp檔案中的applicationDidFinishLaunching()函式中, 想在pDirector->runWithScene(pLandlords);中直接使用replace
Cocos2d-x學習筆記(八)例項——精靈Action
【關於精靈Action】 精靈的動作分為瞬時動作和延時動作,瞬時動作中間不產生任何動畫效果,而延時動作則會產生很多的動畫效果。動畫效果主要還是要靠延時動作類CCActionInterval的子類來實現,其應用例項在TestCpp裡面有很多的例子。 單純的實現一個精靈動作很簡單,只要
Cocos2d-x學習筆記(七)例項——繪製圖形
【關於draw函式】 在節點類CCNode中,可以重寫draw函式並在其中繪製圖形。Draw是一個虛擬函式,只要繼承CCNode的子類都可使用,只要在其函式內部新增繪圖操作即可在場景中顯示繪製的圖形。 【1】為了使繪製的圖形更清晰,將init()裡所有關於佈景的資源(
Cocos2d-x學習筆記(六)例項——多層佈景
【關於多層佈景】 在遊戲開發中,一般會把遊戲分為兩部分:一部分是遊戲介面部分,也就是常說得UI部分;另一部分就是遊戲本身部分。有時UI有很多頁面,在頁面中用的圖也不是很多,不需要進行場景切換,只需把不同頁面做成不同的佈景,然後切換佈景層。那麼就需要一個“管理者”來管理這些介面,這時
Cocos2d-x學習筆記(五)例項——場景切換
【1】首先設計場景需要許多的圖片資源,往resource資料夾裡新增資原始檔: 【2】新建Cocos2d-x工程時預設的是HelloWord場景,在此只做先顯示佈景層中相關精靈圖片以及選單圖片的修改: 【3】在剛剛的init()函式中有兩個選單回撥函式,主要
Cocos2d-x學習筆記(四)淺析動作類CCAction(3)
【1】動作管理類CCActionManager: 動作管理類CCActionManager是一個管理所有動作的單例,可以對動作進行一系列的操作,如:新增動作、刪除動作、暫停動作、重啟動作,這個單例可以通過CCDirector::sharedDirector()->getActionMa
Cocos2d-x學習筆記(三)淺析動作類CCAction(2)
有關CCAction其它動作類簡介: (1)攝像機動作類CCOrbitCamera: 攝像機動作是環繞中心螢幕旋轉所形成的動作,其旋轉座標採用球座標描述。 Create()函式原型CCOrbitCamera* create(fl
Cocos2d-x學習筆記(二)淺析動作類CCAction(1)
Cocos2d-x的動作類CCAction並不是一個在螢幕中顯示的物件,動作必須要依託於CCNode類及其子類的例項才能發揮作用。CCAction繼承於物件類CCObject,有三個子類:有限時間動作、跟隨、移動速度,其中有限時間動作子類CCActionInterVal會形成動畫過程。
Cocos2d-x學習筆記(一)HelloCpp的來龍去脈
【1】首先分析HelloCpp專案的檔案結構,分為Classes、win32、外部檔案依賴三個資料夾,其中外部依賴資料夾暫且不用理會。 Classes主要包含像導演、場景、佈景、攝像機、精靈、App相關類的申明和定義; Win32主要是應用程式框架的WinMain函式入口(包
cocos2d-x學習筆記-CCMenu和CCMenuItem詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
cocos2d-x學習筆記——EventDispatcher事件分發機制
EventDispatcher 事件分發機制先建立事件,註冊到事件管理中心 _eventDispatcher,通過釋出事件得到響應進行回撥,完成事件流。_eventDispatcher是Node的屬性,通過它管理當前節點(場景、層、精靈等)的所有事件的分發。但它
cocos2d-x學習筆記(10)重複動作RepeatForever和Repeat 以及動作組合Sequence和Spawn
Repeat和RepeatForever Sprite* sprite=Sprite::create("sprite.png"); sprite->setPosition(Point(visibleSize.width/2,visibleSize.height/
Cocos2d-x學習筆記(三)CCNode分析
class CC_DLL CCNode : public CCObject { public: CCNode(void); virtual ~CCNode(void); // 初始化節點 virtual bool init(); // 建立一個節點物