自从Cocos2d-x 3.0引用了C++11标准后,回调函数采用的新的函数适配器:std::function、std::bind。而曾经的回调函数menu_selector、callfunc_selector、cccontrol_selector等都已经被无情的抛弃了。取而代之的则是一系列的CC_CALLBACK_*。

【std::bind】

1、CC_CALLBACK_*

Cocos2d-x总共使用了4个std::bind的宏定义,其重点就在于使用了std::bind进行函数适配。

std::placeholders::_1 :不定参数。不事先指定,而是在调用的时候传入。

##__VA_ARGS__ :可变参数列表。

//

// 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)。

//

/**

* 函数动作

* - 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。

如下所示:

//

//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。

//

//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。

//

//创建一个事件监听器类型为 单点触摸

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。

//

//定时器

schedule(schedule_selector(HelloWorld::update), 1.0/60.0);

//回调函数

void HelloWorld::update(float dt) { }

//

3.2、按钮事件回调cccontrol_selector

依旧使用cccontrol_selector。

//

//按钮事件绑定

button->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::callback), Control::EventType::TOUCH_DOWN);

//回调函数

void HelloWorld::callback(Node* sender, Control::EventType controlEvent) { }

//

4、扩展回调函数

在3.x版本中,事件的回调函数可以带任意个自定义的参数。

举个例子:(以菜单项回调函数为例)

请看回调函数callback4。

//

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);

}

//