(2) Cocos2dx 3.x lambda表达式的使用

Cocos2dx 3.0 版本后加入了lambda表达式,或者说C++ 11终于引入了lambda表达式,那么,什么是lambda表达式呢?

例如调用<algorithm>中的std::sort,ISO C++ 98 的写法是要先写一个compare函数:

  1. boolcompare(int&a,int&b)
  2. {
  3. returna>b;//降序排序
  4. }
然后,再这样调用:

    sort(a,a+n,compare);

然而,用ISO C++ 11 标准新增的Lambda表达式,可以这么写:

    inta,87); font-weight:bold; background-color:inherit">intb){returna>b;});//降序排序
这样一来,代码是不是简洁多了呢?
由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导

    autof=[](returna>b;});
和其它语言的一个较明显的区别是Lambda和C++的类型系统结合使用,如: [cpp]view plaincopy

    autof=[=](returna>x;});//x被捕获复制
  1. intx=0,y=1;
  2. autog=[&](intx){return++y;});//y被捕获引用,调用g后会修改y,需要注意y的生存期
  3. bool(*fp)(int,87); font-weight:bold; background-color:inherit">int)=[](//不捕获时才可转换为函数指针

------------------------------------------------------------------------

下面讲下在cocos2dx 3.0 应该如何使用lambda:

我先创建一个menu ,如果不使用labmda,menu里 item 需再写一个回调函数,如下:

    autocloseItem=MenuItemImage::create(
  1. "CloseNormal.png",
  2. "CloseSelected.png",
  3. CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
  4. voidHelloWorld::menuCloseCallback(Object*sender)
  5. {
  6. Director::getInstance()->end();
  7. }
使用了lambda后,可以这么使用:
    [](Object*sender)
  1. Director::getInstance()->end();//直接在这里添加按钮要调用的代码
  2. });
这种写法是不是简洁很多?当然了,也可以将回调 的代码单独取出来,这种写法的好处是可以多出调用callEnd。如下:
    autocallEnd=[](Object*sender)
  1. Director::getInstance()->end();//直接在这里添加按钮要调用的代码
  2. };
  3. autocloseItem=MenuItemImage::create(
  4. allEnd);

默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。
如果要设定表达式能够访问外部变量,可以在 [] 内写入 & 或者 = 加上变量名,其中 & 表示按引用访问,= 表示按值访问,变量之间用逗号分隔,比如 [=factor,&total] 表示按值访问变量 factor,而按引用访问 total。

用 & 引用来举个例子:假设点击按钮后,我要创建一个精灵。修改callEnd:

    autosp=Sprite::create("Hello.png");
  1. sp->setPosition(Point(100,100));
  2. this->addChild(sp,10);//这里报错
  3. };
上面这种写法是错误的,因为表达式无法访问当前作用于的变量。下面继续改代码:
    autocallEnd=[&](Object*sender)
  1. //perfect
  2. };
这样就没问题了。 上面的例子都只是简单的应用。在cocos2dx用到lambda 的地方还有很多,例如创建一个监听事件:

 
 
  1. //Makesprite1touchable
  2. autosprite1=Sprite::create();
  3. autolistener1=EventListenerTouchOneByOne::create();
  4. listener1->setSwallowTouches(true);
  5. listener1->onTouchBegan=[](Touch*touch,Event*event){
  6. autotarget=static_cast<Sprite*>(event->getCurrentTarget());
  7. returnfalse;
  8. };
  9. listener1->onTouchMoved=[](Touch*touch,Event*event){
  10. autotarget=static_cast<Sprite*>(event->getCurrentTarget());
  11. target->setPosition(target->getPosition()+touch->getDelta());
  12. };
  13. listener1->onTouchEnded=[=](Touch*touch,248); margin:0px!important; padding:0px 3px 0px 10px!important">_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,sprite1);
恩,就这样子吧。
本篇博客来自star特530,转载请注明出处http://blog.csdn.net/start530/article/details/19913611

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...