cocos2dx[3.2](11)——新回調函數std::bind
【嘮叨】
自從3.0引用了C++11標準後,回調函數採用的新的函數適配器:std::function、std::bind。
而曾經的回調函數menu_selector、callfunc_selector、cccontrol_selector等都已經被無情的拋棄了。
取而代之的則是一系列的CC_CALLBACK_*。
【致謝】
【std::bind】
0、std::bind
請參照上面兩篇文章。
1、CC_CALLBACK_*
cocos2dx總共使用了4個std::bind的宏定義,其重點就在於使用了std::bind進行函數適配。
> std::placeholders::_1 :不定參數。不事先指定,而是在調用的時候傳入。
> ##__VA_ARGS__ :可變參數列表。
1
2
3
4
5
6
7
| // // 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_CALLBACK_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__) // |
2、變更的回調函數
> 動作函數 :CallFunc/CallFuncN
callfunc_selector / callfuncN_selector / callfuncND_selector
> 菜單項回調:menu_selector
> 觸摸事件 :onTouchBegan / onTouchMoved / onTouchEnded
2.1、動作函數CallFunc
可以直接使用CC_CALLBACK_0、CC_CALLBACK_1,也可以直接使用std::bind。
> CallFunc :使用CC_CALLBACK_0。不帶任何不定參數。
> CallFuncN:使用CC_CALLBACK_1。需要默認傳入不定參數 placeholders::_1,其值為:調用該動作的對象(如sprite->runAction(callfun),那麼默認的一個不定參數 _1 為 sprite)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| // /** * 函數動作 * - CallFunc * - CallFuncN * - CallFuncND與CallFuncO已被遺棄,請使用CallFuncN替代 */ //2.x版本 CallFunc::create ( this , callfunc_selector (HelloWorld::callback0) ); CCCallFuncN::create ( this , callfuncN_selector (HelloWorld::callback1) ); CCCallFuncND::create( this , callfuncND_selector(HelloWorld::callback2), ( void *)10 ); //回調函數 void HelloWorld::callback0() { } //CCCallFunc回調函數 void HelloWorld::callback1(CCNode* node) { } //CCCallFuncN回調函數 void HelloWorld::callback2(CCNode* node, void * a) { } //CCCallFuncND回調函數,參數必須為void* //3.x版本 //使用 CC_CALLBACK_* CallFunc::create ( CC_CALLBACK_0(HelloWorld::callback0, this ) ); CallFuncN::create( CC_CALLBACK_1(HelloWorld::callback1, this ) ); CallFuncN::create( CC_CALLBACK_1(HelloWorld::callback2, this , 0.5)); //使用 std::bind //其中sprite為執行動作的精靈 CallFunc::create (std::bind(&HelloWorld::callback0, this ) ); CallFuncN::create(std::bind(&HelloWorld::callback1, this , sprite); CallFuncN::create(std::bind(&HelloWorld::callback2, this , sprite, 0.5)); //回調函數 void HelloWorld::callback0() { } void HelloWorld::callback1(Node* node) { } void HelloWorld::callback2(Node* node, float a) { } //可自定義參數類型float // |
當然,如果你對於std::bind很熟悉的話,對於CallFunc、CallFuncN回調函數的綁定,也可以全部都使用std::bind。
如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // //callback0 CallFunc::create(std::bind(&HelloWorld::callback0, this )); //callback1 CallFunc::create (std::bind(&HelloWorld::callback1, this , sprite)); CallFuncN::create(std::bind(&HelloWorld::callback1, this , std::placeholders::_1)); //callback2 CallFunc::create (std::bind(&HelloWorld::callback2, this , sprite, 0.5)); CallFuncN::create(std::bind(&HelloWorld::callback2, this , std::placeholders::_1, 0.5)); //回調函數 void HelloWorld::callback0() { } void HelloWorld::callback1(Node* node) { } void HelloWorld::callback2(Node* node, float a) { } //可自定義參數類型float // |
2.2、菜單項回調menu_selector
使用CC_CALLBACK_1,也可以直接使用std::bind。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // //2.x版本 MenuItemImage::create( "1.png" , "2.png" , this , menu_selector(HelloWorld::callback)); //3.x版本 //CC_CALLBACK_1 MenuItemImage::create( "1.png" , "2.png" , CC_CALLBACK_1(HelloWorld::callback1, this )); //std::bind MenuItemImage::create( "1.png" , "2.png" , std::bind(&HelloWorld::callback1, this , std::placeholders::_1)); //回調函數 void HelloWorld::callback(Node* sender) { } // |
2.3、觸控事件回調
使用CC_CALLBACK_2。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // //創建一個事件監聽器類型為 單點觸摸 auto touchLisner = EventListenerTouchOneByOne::create(); //綁定事件 touchLisner->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this ); touchLisner->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this ); touchLisner->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this ); //回調函數 virtual bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event); virtual void HelloWorld::onTouchMoved(Touch *touch, Event *unused_event); virtual void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event); // |
3、未變更的回調函數
3.1、定時器回調schedule_selector
依舊使用schedule_selector。
1
2
3
4
5
6
7
| // //定時器 schedule(schedule_selector(HelloWorld::update), 1.0/60.0); //回調函數 void HelloWorld::update( float dt) { } // |
3.2、按鈕事件回調cccontrol_selector
依舊使用cccontrol_selector。
1
2
3
4
5
6
7
| // //按鈕事件綁定 button->addTargetWithActionForControlEvents( this , cccontrol_selector(HelloWorld::callback), Control::EventType::TOUCH_DOWN); //回調函數 void HelloWorld::callback(Node* sender, Control::EventType controlEvent) { } // |
4、擴展回調函數
在3.x版本中,事件的回調函數可以帶任意個自定義的參數啦。
舉個栗子:(以菜單項回調函數為例)
請看回調函數callback4。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| // auto sprite = Sprite::create( "CloseNormal.png" ); sprite->setPosition(Vec2(visibleSize / 2) ); this ->addChild(sprite); auto itemImage = MenuItemImage::create( "CloseNormal.png" , "CloseNormal.png" , std::bind(&HelloWorld::callback4, this , std::placeholders::_1, sprite, 10, 0.5)); itemImage->setPosition(Vec2(visibleSize / 4)); auto pMenu = Menu::create(itemImage, NULL); pMenu->setPosition(Vec2::ZERO); this ->addChild(pMenu); //回調函數 void HelloWorld::callback4(Node* sender, Sprite* bg, int a, float b) { bg->setScale(a * b); } // |
沒有留言:
張貼留言