`

【cocos2d-x】深入了解CCSprite

 
阅读更多

本章我们将深入了解精灵(Sprite)。我们可以通过很多方式用单个文件或者纹理贴图集(Texture Atlases)来生成精灵。我也会在本章介绍如何创建和播放精灵动画。

  纹理贴图集是一张包含很多图片的纹理贴图(图片),通常用于存放单个角色动画的所有动画帧。不过它的作用不止于此。实际上你可以把任何图片放进同一张纹理贴图中。我们的目的是把尽可能多的图片放进同一张纹理贴图中,以达到节省空间的目的。 我主要用TexturePackerGUI来生成纹理贴图集 

下载地址:TexturePackerGUI  

 “精灵批处理”(Sprite Batching)是用于提高精灵渲染速度的技术。它可以提高渲染大量相同精灵的速度,不过它同纹理贴图集配合使的效率最高。如果你将纹理贴图集与精灵批处理配合使用的话,你只要调用一次渲染方法就可以完成纹理贴图集里所有图片的渲染。

  “渲染方法调用”(draw call)是把必要的信息传递给图形处理硬件以完成整个或者部份图片渲染的过程。当你使用CCSprite的时候,每生成一个CCSprite节点都会调用一次渲染方法。每一次渲染方法调用导致的系统开销叠加起来会使游戏的帧率大约降低15%或者更多(除非你使用CCSpriteBatchNode,它的作用是作为一个额外的层用于添加多个精灵节点。前提是这些精灵节点使用的是同一个纹理贴图)。


CCSpriteBatchNode

  每次系统在屏幕上渲染一张贴图时,图形处理硬件必须首先准备渲染,然后渲染图形,最后在完成渲染以后进行清理。上述过程是每一次在启动渲染和结束渲染之间存在的固定系统开销。如果图形处理硬件知道你需要使用同一张纹理贴图渲染一组精灵的话,图形处理硬件将只需要为这一组精灵执行一次准备,渲染,最后清理的过程了。

 

 你可以看到屏幕上有几百个相同的子弹。如果你逐个渲染它们的话,你的游戏帧率将会下降至少15%。如果你使用CCSpriteBatchNode,你就可以避免帧率的下降。

 

 

把使用同一张纹理贴图的一组CCSprite节点添加到同一个CCSpriteBatchNode里,比逐个渲染CCSprite要高效很多。

以下是生成CCSprite的常用代码:

  1. CCSprite *sprite=CCSprite::create("sprite.png");  
  2. this->addChild(sprite); 

当然,向CCSpriteBatchNode添加一个CCSprite节点不会有任何效率上的提高。

接下来,我把许多使用同一张纹理贴图的精灵节点添加到了同一个CCSpriteBatchNode里

 

  1. CCSpriteBatchNode *node=CCSpriteBatchNode::create("s1.png"); 
  2.         this->addChild(node); 
  3.  
  4.         for(int i=0;i<100;i++){ 
  5.             CCSprite *sprite=CCSprite::create("s1.png"); 
  6.             node->addChild(sprite); 
  7.         } 

  CCSpriteBatchNode的作用很像CCLayer,因为它本身并不显示在屏幕上。不过你只能把CCSprite加入CCSpriteBatchNode。CSpriteBatchNode将一个图片文件名作为参数,使用这个参数的原因是所有被添加进CCSpriteBatchNode的CCSprite节点都必须使用同一个图片文件。如果你没有在CCSprite中使用相同的图片,你将会在调试窗口中得到报错信息。

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

 什么时候应该使用CCSpriteBatchNode?

 

 当你需要显示两个或者更多个相同的CCSprite节点时,你可以使用CCSpriteBatchNode。组合在一起的CCSprite节点越多,使用CCSpriteBatchNode得到的效果提升就越大。

  不过也有一些限制。因为所有的CCSprite节点都添加到同一个CCSpriteBatchNode中,所以所有CCSprite节点都会使用相同的z-order(深度)来渲染.

另一个缺点是所有添加到同一个CCSpriteBatchNode中的CCSprite节点必须使用同一个纹理贴图。不过那也意味着CCSpriteBatchNode非常适合使用纹理贴图集。使用纹理贴图集的时候,你不仅仅局限于渲染一张图片;你可以把不同的图片放到同一个纹理贴图集中,然后利用CCSpriteBatchNode将所有图片渲染出来,以提高渲染速度。

如果把纹理贴图集和CCSpriteBatchNode配合使用的话,之前讨论的z-order渲染问题就变得不那么明显了,因为你可以在单个CCSprite节点里指定不同的zorder值.

 

 

  你可以把CCSpriteBatchNode看成CCLayer,唯一的区别是:CCSpriteBatchNode只接受使用同一张纹理贴图的CCSprite节点。有了这样的认识以后,我相信你会发现很多可以用到CCSpriteBatchNode的地方。


不使用CCSpriteBatchNode运行精灵动画

 

 接下去我们讨论如何运行精灵动画(Sprite Animation)。因为你可以将所有的动画帧放在同一张纹理贴图集里以节省内存,所以这是另一个使用CCSpriteBatchNode的好地方。

 

不使用纹理贴图集将动画添加到Ship类中需要不少的代码

  1. bool MainScene::init() { 
  2.     bool bRet = false
  3.     do { 
  4. //      1. 生成一个CCArray数组。 
  5. //      2. 循环处理每一个动画帧: 
  6. //          a. 为每一个图片生成一个CCTexture2D节点 
  7. //          b. 利用CCTexture2D节点生成一个CCSpriteFrame 
  8. //          c. 把生成的CCSpriteFrame添加到CCArray中 
  9. //      3. 利用CCArray中的动画帧生成一个CCAnimation节点 
  10. //      4. (可选)把CCAnimation添加到一个CCSprite中 
  11. //      5. 使用CCAnimate动作播放动画 
  12.  
  13.         CCSprite *pSprite = CCSprite::create("q0.png"); 
  14.         this->addChild(pSprite); 
  15.         pSprite->setPosition(CCPointMake(100,100)); 
  16.  
  17.         CCArray *array = CCArray::createWithCapacity(5); 
  18.         for (int i = 0; i < 5; i++) { 
  19.             CCString *filename = CCString::createWithFormat("q%i.png", i); 
  20.             CCTexture2D *tt2d = CCTextureCache::sharedTextureCache()->addImage( 
  21.                     filename->getCString()); 
  22.  
  23.             CCSize size = tt2d->getContentSize(); 
  24.             CCLog("size.width=%f,size.height=%f",size.width,size.height); 
  25.             CCRect rect = CCRectMake(0,0,size.width,size.height); 
  26.  
  27.             CCSpriteFrame *frame = CCSpriteFrame::createWithTexture(tt2d, rect); 
  28.             array->addObject(frame); 
  29.         } 
  30.         CCAnimation *tion = CCAnimation::createWithSpriteFrames(array, 0.08f); 
  31.         CCAnimate *mate = CCAnimate::create(tion); 
  32.         CCRepeatForever *repeat = CCRepeatForever::create(mate); 
  33.         pSprite->runAction(repeat); 
  34.  
  35.         bRet = true
  36.     } while (0); 
  37.     return bRet; 

 代码没啥好讲解的  逻辑顺序都在注释中写出


在cocos2d中使用纹理贴图集

 

 “纹理贴图集”可以帮助你节约宝贵的内存资源,也可以帮助提高精灵的渲染速度。因为一张纹理贴图集其实就是一张大图片,你可以使用CCSpriteBatchNode一次性渲染所有它所包含的图片,从而降低内存使用量和提高渲染效率。

 

 

  1. bool MainScene::init() { 
  2.     bool bRet = false
  3.     do { 
  4.  
  5.         CCSprite *pSprite = CCSprite::create(); 
  6.         this->addChild(pSprite); 
  7.         pSprite->setPosition(CCPointMake(100,100)); 
  8.  
  9.         // 加载纹理贴图集的精灵帧(sprite frame);同时加载相同名字的贴图 
  10.         CCSpriteFrameCache *framecache = 
  11.                 CCSpriteFrameCache::sharedSpriteFrameCache(); 
  12.         framecache->addSpriteFramesWithFile("anim.plist"); 
  13.  
  14.         framecache->spriteFrameByName("q0.png"); 
  15.         CCArray *array=CCArray::createWithCapacity(5); 
  16.         // 加载飞船的动画帧 
  17.         for (int i = 0; i < 5; i++) { 
  18.             CCString *string = CCString::createWithFormat("q%i.png", i); 
  19.             CCSpriteFrame *spriteframe=framecache->spriteFrameByName(string->getCString()); 
  20.             array->addObject(spriteframe); 
  21.         } 
  22.         // 使用所有生成的精灵动画帧创建一个动画对象 
  23.         CCAnimation *tion=CCAnimation::createWithSpriteFrames(array,0.5f); 
  24.         // 通过使用CCAnimate动作播放动画 
  25.         CCAnimate *mate=CCAnimate::create(tion); 
  26.         CCRepeatForever *repeat=CCRepeatForever::create(mate); 
  27.         pSprite->runAction(repeat); 
  28.         bRet = true
  29.  
  30.     } while (0); 
  31.     return bRet; 

  因为cocos2d会自动生成所有图片的缓存,所以你需要一个方法来卸载不再需要的贴图内存。大多数情况下,你可以依赖cocos2d来帮你卸载:

  1. CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames(); 
  2. CCTextureCache::sharedTextureCache()->removeUnusedTextures(); 

如果你想在加载新场景之前完全删除所有内存中的贴图,你应该使用以下方法

  1. CCSpriteFrameCache::purgeSharedSpriteFrameCache(); 
  2. CCTextureCache::purgeSharedTextureCache(); 

 

分享到:
评论

相关推荐

    Cocos2d-x初入学堂--&gt;CCSprite基本处理(2)工程

    Cocos2d-x初入学堂--&gt;CCSprite基本处理(2):创建、缩放、旋转、混色;源码和资源都放在包里了

    Cocos2D-X核心类学习

    Cocos2D-X核心类 Cocos2D-X 引擎的设计思路是将游戏中的各个部分抽象成几个概念:导演、场景、布景层及人物精灵。 导演(CCDirector):游戏的组织者和领导者,是整个游戏的负责人、总指挥。导演类制定游戏的运行...

    Cocos2D-X游戏开发技术精解

    第1章 Cocos2D-X引擎的介绍 1 1.1 何为游戏引擎 1 1.1.1 游戏的核心—引擎 1 1.1.2 引擎的特点 2 1.1.3 知名的引擎介绍 4 1.1.4 引擎的分类 5 1.2 Cocos2D-X引擎的来历 8 1.3 引擎的版本 9 1.4 下载与安装 10 1.5 ...

    Cocos2d x手机游戏开发与项目实战详解.part3

     第五章主要介绍Cocos2d-x核心技术,这里包括Cocos2d-x的核心类CCDirector、CCScene、CCNode、CCLayer、CCSprite、CCAction等,通过案例来介绍Cocos2d-x的场景、图层、交互、动作、动画、粒子效果、游戏地图、物理...

    Cocos2d x手机游戏开发与项目实战详解.part1

     第五章主要介绍Cocos2d-x核心技术,这里包括Cocos2d-x的核心类CCDirector、CCScene、CCNode、CCLayer、CCSprite、CCAction等,通过案例来介绍Cocos2d-x的场景、图层、交互、动作、动画、粒子效果、游戏地图、物理...

    cocos2dx 3.x实现精灵色相的修改

    Debug模式下,需要注释掉 CCGLProgramState.h apply() 方法中 switch语句default分支下的断言 调用方法 CSpriteWithHue *sprite = CCSpriteWithHue::create("HelloWorld.png"); sprite-&gt;setHue(4.6);...

    cocos2d-x 自学文档

    一、运动中的加速度 二、拖动间隐效果(比如子弹的运动轨迹) 三、图形绘制 ...cocos2d-x中的CCArray使用注意 十一、屏幕旋转,schedule 和系统语言(后面再看) 十二、音乐音效 十三、CCRenderTexture

    Cocos2d x手机游戏开发与项目实战详解.part2

     第五章主要介绍Cocos2d-x核心技术,这里包括Cocos2d-x的核心类CCDirector、CCScene、CCNode、CCLayer、CCSprite、CCAction等,通过案例来介绍Cocos2d-x的场景、图层、交互、动作、动画、粒子效果、游戏地图、物理...

    cocos2d-x的粒子创建

    CCSprite *pToBar=CCSprite::createWithTexture(texture); pToBar-&gt;setPosition(ccp(400,436)); pToBar-&gt;setScale(0.7f); this-&gt;addChild(pToBar,1); texture=CCTextureCache::sharedTextureCache()-&gt;addImage...

    CCMask:使用 cocos2d-x v2.0 屏蔽 CCSprite

    蒙版CMask 是一个类,它使 Cocos2D-x v2.0 中的掩蔽变得相当容易。 您只需要定义一个对象和一个蒙版。 就是这样! 用法: // Create a mask and an objectCCSprite* mask = CCSprite::create("mask_circle.png");...

    Cocos2d-x学习笔记之CCScene、CCLayer、CCSprite的默认坐标和默认锚点实验

    主要介绍了Cocos2d-x学习笔记之CCScene、CCLayer、CCSprite的默认坐标和默认锚点实验,这是一个非常值得研究的问题,需要的朋友可以参考下

    Cocos2d-x UI开发之CCControlSwitch控件类使用实例

    CCControlSwitch是开关按钮,关于控件使用时的一些配置,请参见文章:UI开发之控件类-CCControlButton。以下的演示中出现的key和value代表什么意思,知道的人说一声。 bool HelloWorld::init... CCSprite::create

    cocos2d-xna 写的一个小游戏demo坦克大战

    最近看到网上介绍cocos2d的资料很多,看了看cocos2d也支持wp7,下载了个 Cocos2d-XNA 安装包,写个小例子玩玩,熟悉下cocos2d 程序很简单,就一个入门级的小游戏,写完后放手机里运行了下效果还可以 开发环境 vs2010,...

    ccsprite播放动画的源代码

    在vs2010+cocos2d-x编译环境下实现的ccsprite精灵类的动画播放

    java对战游戏源码-CoCos2d_android_PVZ:植物大战僵尸游戏,会不断的更新

    Cocos2d是一个大家庭,包括Cocos2d-iphone,Cocos2d-x,Cocos2d-javascript等。而在国内,Cocos2d-x则相对领先。在中国的2D手机游戏开发中,Cocos2d-x引擎的份额超过70%。不同家庭成员之间只是语言不同,而实现的接口...

    cocos2d 总结:三 CCSprite

    NULL 博文链接:https://o0o0o0o.iteye.com/blog/805581

Global site tag (gtag.js) - Google Analytics