cocos2d-x 3.1.1 學習筆記[17] 關於函數的那些勾當,cocos2d-x3.1.1

來源:互聯網
上載者:User

cocos2d-x 3.1.1 學習筆記[17] 關於函數的那些勾當,cocos2d-x3.1.1
對於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;#endifSequence* 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的,神奇的是居然能傳入四個參數,明擺著就是只認定前兩個參數是有效,後面的統統無效。



學到這裡。貌似對這個流程還是比較清楚的嘛。雖然可能還有更多的只是沒有發現,但是我們還有更多的時間沒有用呀!























怎在cocos2d-x 在已有的類裡自訂一個函數?

class CustomBaseSprite : public Sprite{public: void f();};
 
c/c++/cocos2d-x 有沒有平方與的函數?

double pfh(double a, double b)
{
return a*a+b*b;
}
main()
{
double a,b;
scanf("%lf%lf",&a,&b);
printf("%lf",pfh(a,b));
}

double
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.