2016年6月1日 星期三

0601 cocos2dx[3.2](11)——新回調函數std::bind

 cocos2dx[3.2](11)——新回調函數std::bind
http://shahdza.blog.51cto.com/2410787/1550972
【嘮叨】
    自從3.0引用了C++11標準後,回調函數採用的新的函數適配器:std::functionstd::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);
    }
//

沒有留言:

張貼留言

cocos2dx-lua 建立滑鼠監聽

重要關鍵字  EVENT_MOUSE_SCROLL addEventListenerWithSceneGraphPriority      if IsPc() then --建立滑鼠監聽         local listener = cc.EventListenerMouse...