`

【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初学者的学堂中,深入学习CCSprite的基本处理是至关重要的一步。CCSprite是Cocos2d-x引擎中一个核心的组件,它用于显示2D图像,如图片、精灵或动画帧。在这个教程中,我们将探讨如何创建、缩放、旋转以及...

    cocos2d-x API大全中文版2016

    《cocos2d-x API大全中文版2016》是一部详尽的参考资料,旨在为开发者提供关于cocos2d-x框架的全面理解和实践指导。cocos2d-x是一款广泛使用的开源游戏开发框架,它基于cocos2d,并且支持跨平台开发,包括iOS、...

    cocos2d-x3.0rc0 中文API

    本文将详细介绍cocos2d-x 3.0的中文API,帮助开发者深入理解和运用这一强大的工具。 一、基础架构 cocos2d-x基于C++,并支持Lua和JavaScript两种脚本语言。3.0版本对底层进行了优化,提高了性能,同时也引入了更...

    Cocos2d-x横版动作手游完整源码Source

    Cocos2d-x是一款开源的游戏开发...通过深入研究源代码,开发者不仅可以掌握Cocos2d-x框架的用法,还能了解到游戏设计、优化和调试的实践技巧。无论是新手还是经验丰富的开发者,都能从中受益,提升自己的游戏开发技能。

    cocos2d-x AnchorPoint

    总结,了解并熟练运用cocos2d-x中的AnchorPoint是提升游戏开发效率和质量的关键。正确设置锚点可以帮助开发者实现各种复杂动画效果,增强游戏的视觉表现力。通过VS2008和cocos2dx2.0.4的实践,我们可以更深入地学习...

    cocos2d-x 权威指南(高清)

    - **核心类解析**:深入讲解Cocos2D-x中的关键类,如`CCSprite`、`CCMenu`等。 - **动作与动画**:详细介绍如何使用Cocos2D-x实现各种动画效果,如旋转、缩放等。 - **特效实现**:教授如何添加特效增强游戏视觉体验...

    一个都不能死游戏cocos2d-x实现

    在本文中,我们将深入探讨如何使用Cocos2d-x游戏引擎来实现这款游戏。 Cocos2d-x是一款开源的游戏开发框架,基于C++,支持跨平台开发,广泛应用于iOS、Android、Windows等系统。其强大的图形渲染能力和丰富的游戏...

    cocos2d-x-2.2.0.zip 完整版包

    Cocos2d-x是一款开源的游戏开发框架,特别适用于2D游戏、实时渲染应用程序以及互动式教育软件的开发。2.2.0是该框架的一个历史版本,它在当时提供了丰富的功能和性能优化,但随着时间的发展,为了保持最佳的兼容性和...

    cocos2d-x绘制多种颜色字符串

    在Cocos2d-x这个强大的2D游戏开发框架中,绘制多颜色字符串是一个常见的需求,尤其是在制作游戏界面或者实现复杂的文字特效时。标题"“cocos2d-x绘制多种颜色字符串”"涉及到的关键技术点主要集中在如何在Cocos2d-x...

    cocos2d-x游戏源码

    通过对这个闯关类游戏源码的深入学习,你可以了解到cocos2d-x框架的实际运用,理解游戏开发的基本流程,以及如何在实践中解决各种技术问题。这是一个绝佳的学习起点,通过实际操作和调试,你可以逐步提升自己的游戏...

    cocos2d-x简单绘图

    在本文中,我们将深入探讨如何使用Cocos2d-x库进行简单的绘图和动画制作。Cocos2d-x是一个开源的、跨平台的2D游戏开发框架,它基于C++,支持多种操作系统,如iOS、Android、Windows等。在这个例子中,我们将基于...

    cocos2d-android jar包全套.zip

    在Android平台上,Cocos2d-x是一个基于C++的版本,提供了原生的编程接口,同时也支持Java API,方便Android开发者使用。"cocos2d-android jar包全套.zip"这个压缩包包含了在Android上使用Cocos2d开发游戏所需的所有...

    cocos2d-x模态对话框的实现 vs2008实现 带工程

    在Cocos2d-x游戏开发中,模态对话框(Modal Dialog)是一种常见的用户界面元素,用于暂停游戏或应用程序的主线流程,直到用户与对话框交互后才能继续。本项目提供了一个基于Visual Studio 2008的实现,包含完整的...

    Cocos2D-X2.2.3学习笔记5(UI系统)

    本篇学习笔记将深入探讨Cocos2D-X 2.2.3中的UI系统,帮助你掌握如何高效地利用这一功能。 首先,UI系统的核心组件是`CCMenuItem`,它是所有UI元素的基础,如菜单项、按钮等。你可以通过继承`CCMenuItem`并实现其...

    cocos2d-x HelpTest 帮助

    通过探索HelpTest项目,开发者可以了解到cocos2d-x的底层工作原理,学习如何创建游戏场景、添加交互元素、实现动画效果等。同时,对于标签中提到的CCScrollView,可以深入研究其滚动逻辑和事件处理机制,提升游戏UI...

    Cocos2d-x 3.x版本遮罩层 实现捕鱼达人金币表盘效果

    在Cocos2d-x 3.x版本中,为了实现类似捕鱼达人中的金币表盘效果,我们需要利用遮罩层(Mask Layer)技术。遮罩层是一种图形处理技术,它允许我们只显示特定区域内的图像,而隐藏其他部分。在这个场景中,我们将通过...

    Cocos2d-x离线帮助API

    Cocos2d-x是一个流行的开源游戏开发框架,广泛用于创建2D游戏、演示和其他互动内容。Cocos2d-x API是开发者与框架...通过深入学习和掌握这个API,开发者能够充分利用Cocos2d-x的强大功能,创造出引人入胜的游戏体验。

    Cocos2d-X背景重复贴图

    1. **CCSprite**: Cocos2d-X中的精灵类,用于显示图像资源。 2. **CCSpriteBatchNode**: 用于批量渲染多个相同纹理的精灵,可以显著提高渲染效率。 3. **CCRect**: 定义了一个矩形区域,通常用于指定精灵显示的范围...

    学习Cocos2d-X

    总之,学习 Cocos2d-X 需要深入了解其基本架构,熟练掌握显示、交互和声音处理,以及性能优化技术。通过实践项目,不断积累经验,逐步提升游戏开发技能。同时,参考高质量的教程书籍,如《Learn cocos2D Game ...

Global site tag (gtag.js) - Google Analytics