前言:

精灵类是Sprite类。它的子类有PhysicsSprite 和 Skin。

PhysicsSprite 是物理引擎精灵类,而Skin是皮肤精灵类,用于骨骼动画。

创建Sprite精灵对象

创建精灵对象有多种方式,常用的函数如下:

1)创建一个精灵对象,纹理等属性需要在创建后设置

static  Sprite*  create();

2)指定图片创建精灵

static  Sprite*  create(const  std::string&  filename);

3)指定图片和裁剪的矩形区域来创建精灵

static  Sprite*  create(const  std::string&  filename,  const  Rect&  rect);

4)指定纹理创建精灵

static  Sprite*  createWithTexture(Texture2D*  texture);

5)指定纹理和裁剪的矩形区域来创建精灵,第3个参数指定是否旋转纹理,默认不旋转

static  Sprite*  createWithTexture(Texture2D*  texture, const  Rect&  rect,  bool  rotated = false);

6)通过一个精灵帧对象创建另一个精灵对象

static  Sprite*  createWithSpriteFrame(SpriteFrame*  pSpriteFrame);

7)通过指定帧缓存中精灵帧名 创建 精灵对象

static  Sprite*  createWithSpriteFrameName(cosnt  std::string & spriteFrameName);  

使用纹理图集

纹理图集(texture  atlas)也称为精灵表(sprite  sheet),它是把许多小的精灵图片组合到一张大图里面。

使用纹理图集(或精灵表)的优点如下:

1)减少文件读取次数,读取一张图片比读取一堆小文件要快;

2)减少OpenGL  ES绘制调用并且加速渲染;

3)减少内存消耗

4)Cocos2d-x全面支持Zwoptex和 TexturePacker,所以创建和使用纹理图集是很容易的;

通常可以使用TexturePacker设计和生成纹理图集文件,以及纹理图集坐标文件(plist)组成。

通过 Director::getInstance()->getTextureCache() 函数可以获得 TextureCache 实例,TextureCache 的 addImage("tree1.png")函数可以创建纹理Texture2D对象,其中的tree1.png是纹理图片名。

使用纹理对象创建Sprite对象  代码示例:

    auto spbk = Sprite::create("background.png");
     //// 此处没有设置position,默认的位置是 左下角
     //spbk->setPosition(Point(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2));
     spbk->setAnchorPoint(Point::ZERO);
     );

     //// 使用 纹理对象(Texture2D) 创建Sprite对象.
     ///  Rect(float x, float y, float width, float height);
     // 参数rect是 tree1.png图片中,UI坐标系下,(604,38)坐标位置,宽302,高295的一个区域
     auto tree1 = Sprite::create(, , , ));
     tree1->setPosition(Point(, ));
     );

     Texture2D* cache = Director::getInstance()->getTextureCache()->addImage("tree1.png");
     auto tree2 = Sprite::create();
     tree2->setTexture(cache);
     // 参数rect是 tree1.png图片中,UI坐标系下,(73,72)坐标位置,宽182,高270的一个区域
     tree2->setTextureRect(Rect(, , , ));
     tree2->setPosition(Point(, ));
     );

使用精灵帧缓存

精灵帧缓存是缓存的一种。缓存有如下几种:

1)纹理缓存(TextureCache)。使用纹理缓存可以创建纹理对象。上面的部分有介绍。(一张 .png 图片即可)

2)精灵帧缓存(SpriteFrameCache)。能够从精灵表中创建精灵帧缓存,然后再从精灵帧缓存中获得精灵对象,反复使用精灵对象时,使用精灵帧缓存可以节省内存消耗。

(一个 .plist文件 以及 一张和 .plist文件对应的 .png图片)

3)动画缓存(AnimationCache)。动画缓存主要用于精灵动画,精灵动画中的每一帧是从动画缓存中获取的。

这里主要介绍 精灵帧缓存(SpriteFrameCache),要使用精灵帧缓存涉及的类有 SpriteFrameSpriteFrameCache

  SpriteFrameCache* frameCache = SpriteFrameCache::getInstance();
     frameCache->addSpriteFramesWithFile("Demo3/SpriteSheet.plist"); /// 资源目录下必须有 SpriteSheet.png 文件
     auto mountain1 = Sprite::createWithSpriteFrameName("mountain1.png"); // 通过精灵帧(SpriteSheet.png中的一张小图片),创建精灵对象

通过 SpriteFrameCache 创建精灵帧缓存对象,它是采用 单例设计模式进行设计的,getInstance()函数可以获得SpriteFrameCache单一实例,addSpriteFramesWithFile函数是将精灵帧添加到缓存中,其中SpriteSheet.plist 是坐标文件。可以多次调用 addSpriteFramesWithFile 函数添加更多的精灵帧到缓存中。

Sprite::createWithSpriteFrameName("mountain1.png") 是通过Sprite 的 createWithSpriteFrameName 函数创建精灵对象,其中的参数 mountain1.png 是 SpriteSheet.plist 在坐标文件中定义的精灵帧名。  

 /// SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Demo3/SpriteSheet.plist");
     SpriteFrameCache* frameCache = SpriteFrameCache::getInstance();
     frameCache->addSpriteFramesWithFile("Demo3/SpriteSheet.plist");
     auto mountain1 = Sprite::createWithSpriteFrameName("mountain1.png"); /// 通过精灵帧(大图中的一个.png图片) 创建精灵
     mountain1->setAnchorPoint(Point::ZERO);
     mountain1->setPosition(Point(-, ));
     );

 /// SpriteFrameCache::getInstance()->getSpriteFrameByName("hero1.png");
     SpriteFrame* heroSpriteFrame = frameCache->getSpriteFrameByName("hero1.png"); /// 通过 精灵帧 创建 精灵帧对象
     Sprite* hero1 = Sprite::createWithSpriteFrame(heroSpriteFrame); ///通过精灵帧对象(SpriteFrame类型) 创建精灵.
     hero1->setPosition(Point(, ));
     );

精灵帧,精灵帧对象 的概念,有点类似于 变量和变量的指针。都可以用来表示同一个 object,只是表示的方式不一样。

精灵缓存不再使用后要移除相关精灵帧,否则如果再使用相同名称的精灵帧时,就会出现一些奇怪的现象。

移除精灵帧缓存的函数如下:

1)指定具体的精灵帧名移除

void  removeSpriteFrameByName(const std::string& name);

2)指定移除精灵缓存

void  removeSpriteFrames();

3)指定具体的坐标文件移除精灵帧

void  removeSpriteFramesFromFile(const std::string& plist);

4)移除没有使用的精灵帧

void  removeUnusedSpriteFrames();

为了防止该场景中的精灵缓存对下一个场景产生影响,可以在当前场景所在层的onExit函数中调用这些函数。

相关代码如下;

void  HelloWorld::onExit()

{

Layer::onExit();

SpriteFrameCache::getInstance()->removeSpriteFrames();

}

当然,精灵帧缓存清除的工作也可以放到下一个场景创建时。也就是下一个场景所在层的init函数中实现。

cocos2d-x实战 C++卷 学习笔记--第5章 精灵的更多相关文章

  1. cocos2d-x实战 C++卷 学习笔记--第4章 字符串 __String类

    前言: <cocos2d-x实战C++卷>学习笔记.(cocos2d-x 是3.0版本) 介绍 cocos2d-x 通用的字符串类  __String . 使用cocos2d::__Str ...

  2. cocos2d-x实战 C++卷 学习笔记--第7章 动作、特效(一)

    前言: 介绍cocos2d-x中的动作.特效. 动作: 动作(action)包括基本动作和基本动作的组合,这些基本动作有缩放.移动.旋转等,而且这些动作变化的速度也可以设定. 动作类是 Action. ...

  3. cocos2d-x实战 C++卷 学习笔记--第6章 场景与层

    前言: 一个场景(Scene)是由多个层(Layer)组成,而且层的个数要至少是1,不能为0. 场景切换 场景切换相关函数 1)void  runWithScene(Scene*  scene) 该函 ...

  4. cocos2d-x实战 C++卷 学习笔记--第4章 使用菜单

    前言: 菜单中包含菜单项,菜单项类是 MenuItem ,每个菜单项都有三个基本状态:正常.选中和禁止. (MenuItem)菜单分类: (文本菜单)MenuItemLabel : MenuItemA ...

  5. cocos2d-x实战 C++卷 学习笔记--第4章 win32平台下中文乱码问题

    前言: 将GBK编码的字符串转为UTF-8编码.(通俗点说就是解决中文乱码问题) 简要介绍: 在Win32平台下通过 log 输出中文字符时,会出现中文乱码问题.同样的代码在 ios 和 Androi ...

  6. cocos2d-x实战 C++卷 学习笔记--第4章 使用标签

    前言: 介绍cocos2d-x中 标签类. cocos2d-x中 标签类 主要有三种:LabelTTF, LabelAtlas, 和 LabelBMFont.此外,在Cocos2d-x 3.x之后推出 ...

  7. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  8. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  9. Spring实战第八章学习笔记————使用Spring Web Flow

    Spring实战第八章学习笔记----使用Spring Web Flow Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序. 其实我们可以使用任何WEB框架写流程化的应 ...

随机推荐

  1. HTML5要点_CSS(三)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. 使用 StoryBoard 的时候加入用户引导页面

    如果想让一个APP加上引导页面是一个非常完美的举动 但是,总会遇到一些问题 (不要忘记在APDelegate里面加上用户引导页面的头文件和程序启动时的第一个页面哦) 情况一:纯代码 判断是否是第一次启 ...

  3. 关于Hadoop结合RDBMS应用的一些思考

    最近一段时间一直在从事和hadoop相关的工作,主要是技术内容学习.安装配置优化以及一些框架结构的设计.在此期间,我对于RDBMS和Hadoop的结合应用有了一些自己的看法,写出来大家共同探讨一下. ...

  4. linux makefile: c++ 编程_基础入门_如何开始?

    学习android 终究还是需要研究一下其底层框架,所以,学习c++很有必要. 这篇博客,算是linux(ubuntu) 下学习 c++ 的一个入门. 刚开始学习编程语言的时候,最好还是使用命令行操作 ...

  5. Nuget控制台 - 给你的快速添加缺少的包

    利用命令行安装包

  6. 常用Linux运维命令

    1.查看TCP连接状态 netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn netstat -n | awk '/^tcp/ {++S[$NF]} ...

  7. 应聘.net开发工程师常见的面试题(四)

    1.在Asp.net中所有的自定义用户控件都必须继承自________? 答:Control. 2.在.Net中所有可序列化的类都被标记为_____? 答:[serializable] 3.在.Net ...

  8. php中global和$GLOBALS[]的分析之一

    PHP 的全局变量和 C 语言有一点点不同,在 C 语言中,全局变量在函数中自动生效,除非被局部变量覆盖       这可能引起一些问题,有些人可能漫不经心的改变一个全局变量.PHP 中全局变量在函数 ...

  9. 如何用 PHPMailer 来发送邮件?

    <?php require_once('mantisbt-1.2.15/library/phpmailer/class.phpmailer.php'); $mail= new PHPMailer ...

  10. java.lang.NoSuchFieldError: RAW_XML_FILE_HEADER,调用XWPFTemplate动态合并生成一个新的docx文档时报错

    在使用 org.apache.poi 对office文件  根据表单内容和已上次的附件 动态合并成一个新的文档时,本地调试完全ok 但是发布倒Linux环境上就老是报这个错误java.lang.NoS ...