Cocos2dx 3.0 过渡篇(十二) lambda表达式的使用

简介: <pre style="white-space:pre-wrap; word-wrap:break-word; color:rgb(54,46,43); font-size:14px; line-height:26px; background-color:white; font-family:新宋体"><strong>本篇博客来自star特530,转载请注明出处</strong><span
本篇博客来自star特530,转载请注明出处http://blog.csdn.net/start530/article/details/19913611

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

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. bool compare(int & a, int & b)  
  2. {  
  3.     return a > b;   // 降序排序  
  4. }  
然后,再这样调用:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sort(a, a+n, compare);  

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sort(a, a + n, [](int a, int b){return a > b;}); // 降序排序  
这样一来,代码是不是简洁多了呢?

由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto f = [](int a, int b){return a > b;});  
和其它语言的一个较明显的区别是Lambda和C++的类型系统结合使用,如:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片

  1. auto f = [=](int a, int b){return a > x;}); //x被捕获复制  
  2. int x = 0, y = 1;  
  3. auto g = [&](int x){return ++y;}); //y被捕获引用,调用g后会修改y,需要注意y的生存期  
  4. bool(*fp)(intint) = [](int a, int b){return a > b;}); //不捕获时才可转换为函数指针  

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

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

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto closeItem = MenuItemImage::create(  
  2.                                         "CloseNormal.png",  
  3.                                         "CloseSelected.png",  
  4.                                         CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));  
  5.                                           
  6. void HelloWorld::menuCloseCallback(Object* sender)  
  7. {  
  8.     Director::getInstance()->end();  
  9. }  
使用了lambda后,可以这么使用:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto closeItem = MenuItemImage::create(  
  2.                                         "CloseNormal.png",  
  3.                                         "CloseSelected.png",  
  4.                                         [](Object* sender)  
  5.                     {  
  6.                         Director::getInstance()->end();//直接在这里添加按钮要调用的代码  
  7.                     });  
这种写法是不是简洁很多?当然了,也可以将回调 的代码单独取出来,这种写法的好处是可以多出调用callEnd。如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto callEnd = [](Object* sender)  
  2. {  
  3.     Director::getInstance()->end();//直接在这里添加按钮要调用的代码   
  4. };    
  5. auto closeItem = MenuItemImage::create(  
  6.                                         "CloseNormal.png",  
  7.                                         "CloseSelected.png",  
  8.                     allEnd);      

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

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto callEnd = [](Object* sender)  
  2. {  
  3.     auto sp = Sprite::create("Hello.png");  
  4.     sp->setPosition(Point(100,100));  
  5.     this->addChild(sp,10);//这里报错  
  6. };    
上面这种写法是错误的,因为表达式无法访问当前作用于的变量。下面继续改代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto callEnd = [&](Object* sender)  
  2. {  
  3.     auto sp = Sprite::create("Hello.png");  
  4.     sp->setPosition(Point(100,100));  
  5.     this->addChild(sp,10);//perfect  
  6. };    
这样就没问题了。

上面的例子都只是简单的应用。在cocos2dx用到lambda 的地方还有很多,例如创建一个监听事件:

 
 
  1. // Make sprite1 touchable  
  2. auto sprite1 = Sprite::create();  
  3. auto listener1 = EventListenerTouchOneByOne::create();  
  4. listener1->setSwallowTouches(true);  
  5.   
  6. listener1->onTouchBegan = [](Touch* touch, Event* event){  
  7.     auto target = static_cast<Sprite*>(event->getCurrentTarget());  
  8.     return false;  
  9. };  
  10.   
  11. listener1->onTouchMoved = [](Touch* touch, Event* event){  
  12.     auto target = static_cast<Sprite*>(event->getCurrentTarget());  
  13.     target->setPosition(target->getPosition() + touch->getDelta());  
  14. };  
  15.   
  16. listener1->onTouchEnded = [=](Touch* touch, Event* event){  
  17.     auto target = static_cast<Sprite*>(event->getCurrentTarget());  
  18. };                    
  19.   
  20.  _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);                                 
  21.       
恩,就这样子吧。
本篇博客来自star特530,转载请注明出处http://blog.csdn.net/start530/article/details/19913611
相关文章
|
4月前
|
图形学
小功能⭐️Unity静态方法拓展写法
小功能⭐️Unity静态方法拓展写法
|
4月前
|
图形学
小功能⭐️Unity UnityEvent实现代码的选择
小功能⭐️Unity UnityEvent实现代码的选择
|
4月前
|
图形学
小功能⭐️Unity改变代码执行顺序
小功能⭐️Unity改变代码执行顺序
|
4月前
|
图形学
Unity动画☀️Unity动画系统Bug集合
Unity动画☀️Unity动画系统Bug集合
|
4月前
|
图形学
小功能⭐️Unity中一些简便程序写法
小功能⭐️Unity中一些简便程序写法
|
7月前
|
编解码
CocosCreator 面试题(十七)Cocos creator 固定宽度与固定高度的底层原理是什么?Cocos creator是如何做适配的?
CocosCreator 面试题(十七)Cocos creator 固定宽度与固定高度的底层原理是什么?Cocos creator是如何做适配的?
311 0
|
Dart Android开发
Flutter(十七)——组合动画
Flutter(十七)——组合动画
337 2
Flutter(十七)——组合动画
Flutter(十五)——动画的封装与简化
Flutter(十五)——动画的封装与简化
175 1
Flutter(十五)——动画的封装与简化
|
vr&ar 图形学
【100个 Unity小知识点】 | Unity中常用的几种单例写法
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。
|
vr&ar 图形学 索引
【Unity3D 灵巧小知识点】 ☀️ | Unity中如何使用代码切换场景
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。 也可以简单把 Unity 理解为一个游戏引擎,可以用来专业制作游戏!
【Unity3D 灵巧小知识点】 ☀️ | Unity中如何使用代码切换场景
下一篇
DataWorks