zoukankan      html  css  js  c++  java
  • cocos2d-x 3.1.1 学习笔记[17] 关于这些活动功能

    供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__)



    果不其然,宏仅仅是表面。内在还是偷偷的和std::bind勾搭在一起了!


    我们来看下这个到处勾搭的宏是怎么定义的~~~
    #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
    #define CC_CALLBACK_0( 方法,目标, 可变參数) std::bind(&取方法的地址,目标, 可变參数)
    PS:在定义宏的时候是不能用...来当作前面的...作为可变參数的,必需要使用##__VA_ARGS__这个伟大的第三者来替换掉


    可变參数在整个cocos-x中也还是用到非常多的。比方创建Sequence::create就是运动了,不然你怎么能在创建一连串的动作的时候传入那么多的參数的说。


    那么接下来就来看看源代码吧。

    (又是源代码- -)


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


    能够发现多个參数的的时候必需要有一个能够终止的条件(比如最后一个为-1)。可是假设在中途就要传入-1怎么办?
    这个时候仅仅能把传入的參数改为int*
        void manyArgument(int* num, ...);
    然后再把最后终止的条件换为!= null,可是这样在传入參数的时候就麻烦(有得必有失)


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



    接着试试定义一个可变參数得宏  ##__VA_ARGS__ 就代表着前面传入进来的可变參数

        #define MANYARGUMENT(__num__, ...) manyArgument(__num__, ##__VA_ARGS__)
        MANYARGUMENT(arr, arr+1, arr+2, nullptr);

    别忘记我们还有std::placeholders::_1 占位没有玩过呢= =


        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的,奇妙的是竟然能传入四个參数,明摆着就是仅仅认定前两个參数是有效的,后面的统统无效。



    学到这里。

    貌似对这个流程还是比較清楚的嘛。尽管可能还有很多其它的仅仅是没有发现,可是我们还有很多其它的时间没实用呀!



    转摘请注明出处:http://blog.csdn.net/zhouyunxuan



















    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    GIS的核心价值——服务
    Arcgis Add-In开发入门实例
    Arcgis for Androd API开发系列教程(一)——地图显示与GPS定位
    Spring
    字体大小对照换算表
    属性和字段的区别
    sqlDataAdapter和SqlCommand的区别
    C# 连接SQL Server数据库的几种方式--server+data source等方式
    c# using的作用
    random
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4851890.html
Copyright © 2011-2022 走看看