标签:cocos2d-x
对于cocos2d-x经常要用到的方法,不得不好好研究一下,这次的研究真心有收获。为了动作能够回调我们的函数,我们必须先声明并实现他们。
void callBack(); void callBack_1(Node* node); void callBack_2(Node* node,const char* str); void Nice::callBack() { log("Nice::callBack()"); } void Nice::callBack_1(Node* node) { log("This tag is %d",node->getTag()); } void Nice::callBack_2(Node* node,const char* str) { log("This tag is %d, and str is %s",node->getTag(), str); } //然后就开始创建我们伟大的精灵了。 sp_area = Sprite::create("newAlwaysShow.png");//sp_area is a class member ,Sprite* ap_area; sp_area->setTag(1314); auto sp_another = Sprite::create(); sp_another->setTag(520); addChild(sp_another); addChild(sp_area); //翻滚吧,可爱的精灵们! /* CallFunc 创建的函数必须是无参数的 CallFuncN 创建的函数可以是一个至多个参数 */ sp_area->runAction(Sequence::create(MoveTo::create(2, Vec2(200, 200)), CallFunc::create(CC_CALLBACK_0(Nice::callBack, this)), CallFuncN::create(CC_CALLBACK_1(Nice::callBack_2, this, "I have tow parameter")), NULL)); //这样写完之后,发现runAction里面的东西好平淡(平淡有时候才不是真呢!),于是我就瞎写一通,残忍的把它变成了这个样子。 sp_area->runAction(Sequence::create(MoveTo::create(2, Vec2(200, 200)), CallFunc::create(CC_CALLBACK_0(Nice::callBack, this)), CallFunc::create([&]()->void{log("Done1");log("This tag is %d", sp_area->getTag());}), CallFunc::create(std::bind(&Nice::callBack, this)), CallFuncN::create(CC_CALLBACK_1(Nice::callBack_1, this)),//1314 CallFuncN::create(CC_CALLBACK_0(Nice::callBack_1, this, sp_another)),//520 CallFuncN::create([](Node* node){log("this tag is %d", node->getTag());}),//1314 CallFuncN::create(std::bind(&Nice::callBack_1, this, sp_area)),//1314 CallFuncN::create(std::bind(&Nice::callBack_1, this, sp_another)),//520 CallFuncN::create(CC_CALLBACK_1(Nice::callBack_2, this, "I have tow parameter")), NULL));
好吧,他现在已经面目全非了。其实这么多行也只是用到了两种方法而已,第一种lambda表达式,第二种std::bind()。(尼玛,你在逗我吗?不是还有CC_CALLBACK_0吗?)
额。既然这样就让我们来看下源码吧!
// 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__)
Sequece::create是分平台实现的(分为win和其他) #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) // WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported typedef FiniteTimeAction* M; static Sequence* create(M m1, std::nullptr_t listEnd) { return variadicCreate(m1, NULL); } static Sequence* create(M m1, M m2, std::nullptr_t listEnd) { return variadicCreate(m1, m2, NULL); } static Sequence* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); } static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); } // On WP8 for variable argument lists longer than 10 items, use the other create functions or variadicCreate with NULL as the last argument static Sequence* variadicCreate(FiniteTimeAction* item, ...); #else static Sequence* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION; #endif Sequence* Sequence::create(FiniteTimeAction *action1, ...) { va_list params; va_start(params, action1); Sequence *ret = Sequence::createWithVariableList(action1, params);//传给了createWithVariableList让他来处理 va_end(params); return ret; } Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args) { FiniteTimeAction *now; FiniteTimeAction *prev = action1; bool bOneAction = true; while (action1) { now = va_arg(args, FiniteTimeAction*); //如果第二个动作存在 if (now) { prev = createWithTwoActions(prev, now); bOneAction = false; } //如果第二个动作不存在 else { // If only one action is added to Sequence, make up a Sequence by adding a simplest finite time action. if (bOneAction) { prev = createWithTwoActions(prev, ExtraAction::create()); } break; } } return ((Sequence*)prev); }
void manyArgument(int num, ...); void Nice::manyArgument(int num, ...) { va_list params; //va_start函数的第二个参数要和manyArgument的第一个参数一样 va_start(params, num); int now; log("fist is %d", num); while (true) { now = va_arg(params, int); if (now != -1) { log("now is %d", now); } else { break; } } va_end(params); } manyArgument(1, 2, 3, 4, -1);
void manyArgument(int* num, ...); void Nice::manyArgument(int* num, ...) { va_list params; //va_start函数的第二个参数要和manyArgument的第一个参数一样 va_start(params, num); int* now; log("fist is %d", *num); while (true) { now = va_arg(params, int*); if (now != nullptr) { log("now is %d", *now); } else { break; } } va_end(params); } int arr[] {3,6,9,12}; manyArgument(arr, arr+1, arr+2, arr+3, nullptr);
#define MANYARGUMENT(__num__, ...) manyArgument(__num__, ##__VA_ARGS__) MANYARGUMENT(arr, arr+1, arr+2, nullptr);
auto add_num = std::bind(&Nice::add, this, std::placeholders::_1, std::placeholders::_2, 10); log("sum is %d", add_num(1, 1));//12 log("sum is %d", add_num(1, 1, 2));//12 log("sum is %d", add_num(1, 1, 2, 4));//12 //无论怎么改变参数的第三位也是固定死了是10的,神奇的是居然能传入四个参数,明摆着就是只认定前两个参数是有效的,后面的统统无效。
学到这里。貌似对这个流程还是比较清楚的嘛。虽然可能还有更多的只是没有发现,但是我们还有更多的时间没有用呀!
cocos2d-x 3.1.1 学习笔记[17] 关于函数的那些勾当
标签:cocos2d-x
原文地址:http://blog.csdn.net/zhouyunxuan/article/details/38038017