由于引入了C++ 11特性,cocos2d-x 3.x中许多实现方案,相对于以前的cocos2d-x 2.x,都有了很大的改进,当然性能上也得到一定的提升。
本文关注的是回调函数从2.x到3.x的变化。
cocos2d-x 2.x时代的回调函数
2.X时代主要使用CCCallFunc、CCCallFuncN和CCCallFuncND等几种方式实现。
CCCallFunc、CCCallFuncN和CCCallFuncND都用来创建带有回调函数的动作,区别主要在于回调函数是否带有参数。
2.x时代实例
testCallFunc.h中代码: class testCallFunc : public CCLayer{protected: CCSprite* sprite1; CCSprite* sprite2; CCSprite* sprite3;public: virtual void onEnter(); void callback1(); void callback2(CCNode* sender); void callback3(CCNode* sender, void* data); }; testCallFunc.cpp中代码: void testCallFunc::onEnter(){ //CCCallFunc的使用 CCFiniteTimeAction* action = CCSequence::create( CCMoveBy::create(2, ccp(200,0)), CCCallFunc::create(this, callfunc_selector(testCallFunc::callback1)), NULL); //CCCallFuncN的使用 CCFiniteTimeAction* action2 = CCSequence::create( CCScaleBy::create(2 , 2), CCFadeOut::create(2), CCCallFuncN::create(this, callfuncN_selector(testCallFunc::callback2)), NULL); //CCCallFuncNC的使用 CCFiniteTimeAction* action3 = CCSequence::create( CCRotateBy::create(3 , 360), CCFadeOut::create(2), CCCallFuncND::create(this, callfuncND_selector(testCallFunc::callback3), (void*)0xbebabeba), NULL); sprite1->runAction(action); sprite2->runAction(action2); sprite3->runAction(action3); } void testCallFunc::callback1(){ CCSize s = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create("callback 1 called", "Marker Felt", 16); label->setPosition(ccp( s.width/4*1,s.height/2)); addChild(label); } void testCallFunc::callback2(CCNode* pSender){ CCSize s = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create("callback 2 called", "Marker Felt", 16); label->setPosition(ccp( s.width/4*2,s.height/2)); addChild(label); } void testCallFunc::callback3(CCNode* pTarget, void* data){ CCSize s = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create("callback 3 called", "Marker Felt", 16); label->setPosition(ccp( s.width/4*3,s.height/2)); addChild(label); }
cocos2d-x 3.x时代
由于引用了std::function等支持,回调函数得到极大简化处理。归纳如下:
CallFunc 可以由 std::function<void()> 来创建
CallFuncN 可以由 std::function<void(Node*)> 来创建
CallFuncND 和 CallFuncO 已经被移除了因为它们可以类似地由 CallFuncN 和 CallFunc 来创建。
可以查看示例中的 ActionsTest.cpp 文件,同时注意MenuItem 支持 std::function<void(Node*)> 作为回调。
CallFunc 示例:
// v2.1 版本
CCCallFunc *action1 = CCCallFunc::create( this, callfunc_selector( MyClass::callback_0 ) );
// v3.0 版本 (短版本)
auto action1 = CallFunc::create( CC_CALLBACK_0(MyClass::callback_0,this)); auto action2 = CallFunc::create( CC_CALLBACK_0(MyClass::callback_1,this, additional_parameters));
// v3.0 版本 (长版本)
auto action1 = CallFunc::create( std::bind( &MyClass::callback_0, this)); auto action2 = CallFunc::create( std::bind( &MyClass::callback_1, this, additional_parameters));
// v3.0 中你也可以使用lambda表达式或者其他函数对象
auto action1 = CallFunc::create( [&](){ auto s = Director::sharedDirector()->getWinSize(); auto label = LabelTTF::create("called:lambda callback", "Marker Felt", 16); label->setPosition(ccp( s.width/4*1,s.height/2-40)); this->addChild(label); } );
MenuItem 示例:
// v2.1 版本
CCMenuItemLabel *item = CCMenuItemLabel::create(label, this, menu_selector(MyClass::callback));
// v3.0 版本 (短版本)
auto item = MenuItemLabel::create(label, CC_CALLBACK_1(MyClass::callback, this));
// v3.0 版本 (长版本)
auto item = MenuItemLabel::create(label, std::bind(&MyClass::callback, this, std::placeholders::_1));
// v3.0 中你也可以使用lambda表达式或者其他函数对象
auto item = MenuItemLabel::create(label, [&](Object *sender) { // do something. Item "sender" clicked });