忍者无敌-实例讲解Cocos2d-x瓦片地图

实例比较简单,如图所示,地图上有一个忍者精灵,玩家点击他周围的上、下、左、右,他能够向这个方向行走。当他遇到障碍物后是无法穿越的,障碍物是除了草地以为部分,包括了:树、山、河流等。




忍者实例地图(Todo用这个精灵替换图中的



设计地图
我们采用David Gervais提供开源免费瓦片集,下载的文件dg_grounds32.gif,gif文件格式会有一定的问题,我们需要转换为.jpg或.png文件。本实例中我是使用PhotoShop转换为dg_grounds32.jpg。

David Gervais提供的瓦片集中的瓦片是32 x 32像素,我们创建的地图大小是32 x 32瓦片。我们先为地图添加普通层和对象层,普通层按照上图设计,对象层中添加几个矩形区域对象,这里不再赘述。这个阶段设计完成的结果如图所示。保存文件名为MiddleMap.tmx,保存目录Resources\map。



设计地图

程序中加载地图
地图设计完成我们就可以在程序中加载地图了。下面我们再看看具体的程序代码,首先看一下HelloWorldScene.h文件,它的代码如下:
[html] view plain copy
  1. #ifndef__HELLOWORLD_SCENE_H__
  2. #define__HELLOWORLD_SCENE_H__
  3. #include"cocos2d.h"
  4. classHelloWorld:publiccocos2d::Layer
  5. {
  6. cocos2d::TMXTiledMaP*_tileMap;①
  7. cocos2d::Sprite*_player;②
  8. public:
  9. staticcocos2d::Scene*createScene();
  10. virtualboolinit();
  11. CREATE_FUNC(HelloWorld);
  12. };
  13. #endif//__HELLOWORLD_SCENE_H__

上述代码第①行代码是定义成员变量地图成员_tileMap,。第②行代码是定义精灵成员变量_player。
HelloWorldScene的实现代码HelloWorldScene.ccp文件,它的HelloWorld::init()代码如下:
copy
    boolHelloWorld::init()
  1. {
  2. if(!Layer::init())
  3. returnfalse;
  4. }
  5. SizevisibleSize=Director::getInstance()->getVisibleSize();
  6. Pointorigin=Director::getInstance()->getVisibleOrigin();
  7. _tileMap=TMXTiledMap::create("map/MiddleMap.tmx");①
  8. addChild(tileMap,100);②
  9. TMXObjectGrouP*group=_tileMap->getobjectGroup("objects");③
  10. ValueMapspawnPoint=group->getobject("ninja");④
  11. floatx=spawnPoint["x"].asFloat();⑤
  12. floaty=spawnPoint["y"].asFloat();⑥
  13. _player=Sprite::create("ninja.png");⑦
  14. _player->setPosition(Point(x,y));⑧
  15. addChild(_player,2,200);
  16. returntrue;
  17. }

上述第①代码是创建TMXTiledMap对象,地图文件是MiddleMap.tmx,map是资源目录Resources下的子目录。TMXTiledMap对象也是Node对象,需要通过第②行代码添加到当前场景中。
第③行代码是通过对象层名objects获得层中对象组集合。第④行代码是从对象组中,通过对象名获得ninja对象信息,它的返回值类型是ValueMap,ValueMap是一种“键-值”对结构。第⑤行代码float x = spawnPoint["x"].asFloat()中的spawnPoint["x"]就是从按照x键取出它的值,即x轴坐标。spawnPoint["x"]的返回值是Value类型,还需要使用asFloat()函数转换为基本的int类型。类似地,第⑥行代码是获得y轴坐标。
第⑦行代码是创建精灵_player,第⑧行代码是设置精灵位置,这个位置是从对象层中ninja对象信息获取的。

加载地图(Todo重新截取,或者换精灵)

移动精灵
移动精灵是通过触摸事件实现移动的,需要在层中进行事件处理,我们需要在层中重写如下函数
bool onTouchBegan(Touch * touch,Event* unused_event)
void onTouchEnded(Touch * touch,51); font-family:Arial; font-size:14px; line-height:26px">void onTouchMoved(Touch * touch,51); font-family:Arial; font-size:14px; line-height:26px">下面我们再看看具体的程序代码,首先看一下HelloWorldScene.h文件,它的代码如下:
copy
    cocos2d::TMXTiledMaP*_tileMap;
  1. cocos2d::Sprite*_player;
  2. virtualboolonTouchBegan(cocos2d::Touch*touch,cocos2d::Event*event);①
  3. virtualvoidonTouchMoved(cocos2d::Touch*touch,cocos2d::Event*event);
  4. virtualvoidonTouchEnded(cocos2d::Touch*touch,cocos2d::Event*event);②
  5. CREATE_FUNC(HelloWorld);
  6. };
  7. #endif//__HELLOWORLD_SCENE_H__

上述代码第①~②行代码是声明触摸事件函数。HelloWorldScene的实现代码HelloWorldScene.ccp文件,它的HelloWorld::init()代码如下:
copy
    ……
  1. setTouchEnabled(true);
  2. //设置为单点触摸
  3. setTouchMode(Touch::dispatchMode::ONE_BY_ONE);
  4. returntrue;
  5. }

上述代码setTouchEnabled(true)是使层开始触摸事件支持代码setTouchMode(Touch::dispatchMode::ONE_BY_ONE)是设置触摸模式为单点触摸。
HelloWorldScene.ccp文件的触摸事件函数代码如下:
copy
    boolHelloWorld::onTouchBegan(Touch*touch,Event*event)
  1. log("onTouchBegan");
  2. }
  3. voidHelloWorld::onTouchMoved(Touch*touch,Event*event)
  4. log("onTouchMoved");
  5. voidHelloWorld::onTouchEnded(Touch*touch,248)"> log("onTouchEnded");
  6. PointtouchLocation=touch->getLocation();①
  7. PointplayerPos=_player->getPosition();②
  8. Pointdiff=touchLocation-playerPos;③
  9. if(abs(diff.x)>abs(diff.y)){④
  10. if(diff.x>0){⑤
  11. playerPos.x+=_tileMap->getTileSize().width;
  12. _player->runAction(FlipX::create(false));⑥
  13. }else{
  14. playerPos.x-=_tileMap->getTileSize().width;
  15. >runAction(FlipX::create(true));⑦
  16. if(diff.y>0){⑧
  17. playerPos.y+=_tileMap->getTileSize().height;
  18. }else{
  19. playerPos.y-=_tileMap->setPosition(playerPos);⑨
  20. 上述第①代码touch->getLocation()是获得在Open GL坐标,Open GL坐标的坐标原点是左下角,touch对象封装了触摸点对象。第②行代码_player->getPosition()是获得精灵的位置。
    第③行代码是获得触摸点与精灵位置之差。第④行代码是比较一下触摸点与精灵位置之差,是y轴之差大还是x轴之差大,那个轴之差大就沿着那个轴移动,(abs(diff.x) > abs(diff.y))情况是x轴之差大,否则是y轴之差大。第⑤行代码,diff.x > 0情况是沿着x轴正方向移动,否则情况是沿着x轴负方向移动。第⑥行代码_player->runAction(FlipX::create(false))是把精灵翻转回原始状态。第⑦行代码_player->runAction(FlipX::create(true))是把精灵是沿着y轴水平翻转。
    第⑧行代码是沿着y轴移动,diff.y > 0是沿着y轴正方向移动,否则是沿着y轴负方向移动。
    第⑨行代码是重新设置精灵坐标。
    检测碰撞
    到目前为止我们游戏中的精灵,可以穿越任何障碍物。为了能够检测到精灵是否碰撞到障碍物,我们需要再添加一个普通层(collidable),它的目的不是现实地图,而是检测碰撞。我们在检测碰撞层中使用瓦片覆盖background层中的障碍物之上,如图所示。
    检测碰撞层 检测碰撞层中的瓦片集可以是任何的满足格式要求的图片文件。在本例中我们使用一个32 x 32像素单色jpg图片文件collidable_tiles. jpg,它的大小与瓦片大小一样,也就是说这个瓦片集中只有一个瓦片。导入这个瓦片集到地图后,我们需要为瓦片添加一个自定义属性,瓦片本身也有一些属性,例如:坐标属性x和y。
    我们要添加属性名为“Collidable”,属性值为“true”。添加过程如图所示,首先,选择collidable_tiles瓦片集中的要设置属性的瓦片。然后,点击属性视图中左下角“+”按钮,添加自定义属性,这时候会弹出一个对话框,我们在对话框中输入自定义属性名“Collidable”,点击确定按钮。这时候回到属性视图,Collidable在属性后面是可以输入内容的,这里我们输入“true”。
    添加检测碰撞属性 地图修改完成后,我们还要修改代码。首选在头文件HelloWorldScene.h中添加一个成员变量和两个函数的声明。
    copy
      #include"SimpleAudioEngine.h"
    1. classHelloWorld:publiccocos2d::Layer
    2. cocos2d::TMXTiledMaP*_tileMap;
    3. cocos2d::TMXLayer*_collidable;①
    4. voidsetPlayerPosition(cocos2d::Pointposition);②
    5. cocos2d::PointtileCoordFromPosition(cocos2d::Pointposition);③
    6. 上述代码第①行是声明一个TMXLayer类型的成员变量,它是用来保存地图碰撞层对象。第②行代码setPlayerPosition函数是重新设置精灵的位置,在这函数中可以检测精灵是否与障碍物碰撞。第③行代码tileCoordFromPosition函数是把像素坐标点转换为地图瓦片坐标点。
      修改HelloWorldScene.cpp中的HelloWorld::init()代码如下:
      copy
        _tileMap=TMXTiledMap::create("map/MiddleMap.tmx");
      1. addChild(_tileMap,100);
      2. >getobjectGroup("objects");
      3. >getobject("ninja");
      4. floatx=spawnPoint["x"].asFloat();
      5. floaty=spawnPoint["y"].asFloat();
      6. _player=Sprite::create("ninja.png");
      7. _collidable=_tileMap->getLayer("collidable");①
      8. _collidable->setVisible(false);②
      9. 我们需要在HelloWorld::init()函数中创建并初始化碰撞层。第①行代码是_collidable = _tileMap->getLayer("collidable")是通过层名字collidable创建层,第②行代码_collidable->setVisible(false)是设置层隐藏,我们要么在这里隐藏的,要么在地图编辑的时候,将该层透明,如图所示,在层视图中选择层,然后通过滑动上面的透明度滑块来改变层的透明度,在本例中是需要将透明度设置为0,那么_collidable->setVisible(false)语句就不再需要了。
        注意 在地图编辑器中,设置层的透明度为0与设置层隐藏,在地图上看起来一样,但是有着本质的区别,设置层隐藏是无法通过_collidable = _tileMap->getLayer("collidable")语句访问的。
        设置层透明度
        我们在前面也介绍过,collidable层不是用来显示地图内容的,而是用来检测碰撞的。修改HelloWorldScene.cpp中的
        copy
          HelloWorld::onTouchEnded代码如下:
        1. //获得在OpenGL坐标
        2. >getLocation();
        3. >getPosition();
        4. Pointdiff=touchLocation-playerPos;
        5. if(abs(diff.x)>abs(diff.y)){
        6. if(diff.x>0){
        7. playerPos.x+=_tileMap->runAction(FlipX::create(false));
        8. playerPos.x-=_tileMap->runAction(FlipX::create(true));
        9. if(diff.y playerPos.y+=_tileMap->getTileSize().height;
        10. playerPos.y-=_tileMap- this->setPlayerPosition(playerPos);①
        11. HelloWorld::onTouchEnded有一些变化,第①行代码this->setPlayerPosition(playerPos)替换了_player->setPosition(playerPos),setPlayerPosition是我们自定的函数,这个函数的作用是移动精灵和检测碰撞。
          setPlayerPosition代码如下:
          copy
            voidHelloWorld::setPlayerPosition(Pointposition)
          1. //从像素点坐标转化为瓦片坐标
          2. PointtileCoord=this->tileCoordFromPosition(position);①
          3. //获得瓦片的GID
          4. inttileGid=_collidable->getTileGIDAt(tileCoord);②
          5. if(tileGid>0){③
          6. Valueprop=_tileMap->getPropertiesForGID(tileGid);④
          7. ValueMappropValueMap=prop.asValueMap();⑤
          8. std::stringcollision=propValueMap["Collidable"].asstring();⑥
          9. if(collision=="true"){//碰撞检测成功⑦
          10. CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("empty.wav");⑧
          11. return;
          12. >setPosition(position);
          13. 上述代码第①行this->tileCoordFromPosition(position)是调用函数,实现从像素点坐标转化为瓦片坐标。第②行代码_collidable->getTileGIDAt(tileCoord)是通过瓦片坐标获得GID值。
            第③行代码tileGid > 0可以判断瓦片是否存在,tileGid == 0是瓦片不存在情况。第④行代码_tileMap->getPropertiesForGID(tileGid)是通过地图对象的getPropertiesForGID返回,它的返回值是Value类型。
            由于Value类型可以代表很多类型。因此第⑤行代码prop.asValueMap()是将Value类型转换成为ValueMap,ValueMap类是“键-值”对。第⑥行代码propValueMap["Collidable"].asstring()是将propValueMap变量中的Collidable属性取出来,asstring()函数可以将Value类型转换成为std::string类型。第⑦行代码collision == "true"是碰撞检测成功情况。第⑧行代码是碰撞检测成功情况下处理,在本例中我们是播放一下音效。
            tileCoordFromPosition代码如下:
            copy
              PointHelloWorld::tileCoordFromPosition(Pointpos)
            1. intx=pos.x/_tileMap->getTileSize().width;①
            2. inty=((_tileMap->getMapSize().height*_tileMap->getTileSize().height)-pos.y)/
            3. _tileMap->getTileSize().height;②
            4. returnPoint(x,y);
            5. 在该函数中第①行代码pos.x / _tileMap->getTileSize().width是获得x轴瓦片坐标(单位是瓦片数),pos.x是触摸点x轴坐标(单位是像素),_tileMap->getTileSize().width是每个瓦片的宽度,单位是像素。代码第②行是获得y轴瓦片坐标(单位是瓦片数),这个计算有点麻烦,瓦片坐标的原点在左上角,而触摸点使用的坐标是Open GL坐标,坐标原点在左下角,表达式(_tileMap->getMapSize().height * _tileMap->getTileSize().height) - pos.y)是反转坐标轴,结果除以每个瓦片的高度_tileMap->getTileSize().height,就得到y轴瓦片坐标了。
              滚动地图
              由于地图比屏幕要大,当我们移动精灵到屏幕的边缘时候,那些处于屏幕之外的地图部分,应该滚动到屏幕之内。这些需要我们重新设置视点(屏幕的中心点),使得精灵一直处于屏幕的中心。但是精灵太靠近地图的边界时候,他有可能不在屏幕的中心。精灵与地图的边界距离的规定是,左右边界距离不小于屏幕宽度的一半,否则会出现图所示的左右黑边问题。上下边界距离不小于屏幕高度的一半,否则也会在上下黑边问题。
              重新设置视点实现的方式很多,本章中采用移动地图位置实现这种效果
              我们在HelloWorldScene.cpp中再添加一个函数setViewpointCenter,添加代码如下:
              copy
                voidHelloWorld::setViewpointCenter(Pointposition)
              1. intx=MAX(position.x,visibleSize.width/2);①
              2. inty=MAX(position.y,visibleSize.height/2);②
              3. x=MIN(x,(_tileMap->getMapSize().width*_tileMap->getTileSize().width)
              4. -visibleSize.width/2);③
              5. y=MIN(y,0); font-weight:bold; background-color:inherit">>getTileSize().height)
              6. -visibleSize.height/2);④
              7. //屏幕中心点
              8. PointpointA=Point(visibleSize.width/2,visibleSize.height/2);⑤
              9. //使精灵处于屏幕中心,移动地图目标位置
              10. PointpointB=Point(x,y);⑥
              11. log("目标位置(%f,%f)",pointB.x,pointB.y);
              12. //地图移动偏移量
              13. Pointoffset=pointA-pointB;⑦
              14. log("offset(%f,offset.x,offset.y);
              15. >setPosition(offset);⑧
              16. 在上述代码①~④是保障精灵移动到地图边界时候不会再移动,防止屏幕超出地图之外,这一点非常重要。其中第①行代码是防止屏幕左边超出地图之外,MAX(position.x,visibleSize.width / 2)语句表示当position.x < visibleSize.width / 2情况下,x轴坐标始终是visibleSize.width / 2,即精灵不再向左移动。第②行代码与第①行代码类似,不再解释。第③行代码是防止屏幕右边超出地图之外,MIN(x,(_tileMap->getMapSize().width * _tileMap->getTileSize().width) - visibleSize.width / 2)语句表示当x > (_tileMap->getMapSize().width * _tileMap->getTileSize().width) - visibleSize.width / 2时候,x轴坐标始终是(_tileMap->getMapSize().width * _tileMap->getTileSize().width) - visibleSize.width / 2表达式计算的结果。
                提示visibleSize 是表示屏幕的宽度,_tileMap->getMapSize().width * _tileMap->getTileSize().width) - visibleSize.width / 2表达式计算的是地图的宽度减去屏幕宽度的一半。
                第④行代码与第③行代码类似,不再解释。
                屏幕左边超出地图
                屏幕右边超出地图 代码⑤~⑧行实现了移动地图效果,使得精灵一直处于屏幕的中心。A点是目前屏幕的中心点,也是精灵的位置。玩家触摸B点,精灵会向B点移动。为了让精灵保持在屏幕中心,地图一定要向相反的方向移动。
                第⑤行代码Point pointA = Point(visibleSize.width/2,visibleSize.height/2)是获取屏幕中心点(A点)。第⑥行代码获取移动地图目标位置(B点)。第⑦行代码是计算A点与B点两者之差,这个差值就是地图要移动的距离。由于精灵的世界坐标就是地图层的模型坐标,即精灵的坐标原点是地图的左下角,因此第⑧行代码this->setPosition(offset)是将地图坐标原点移动offset位置。

                移动地图

                版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

                相关推荐


                    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
                Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
                第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
                    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
                1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
                   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
                 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
                分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
                1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
                原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
                2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
                原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
                环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
                1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
                原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
                原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
                为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
                Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
                需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
                v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是