`

Cocos2d-x优化中纹理优化

阅读更多

1.纹理像素格式
纹理优化工作的另一重要的指标是纹理像素格式,能够最大程度满足用户对保真度要求的情况下,选择合适的像素格式,可以大幅提高纹理的处理速度。而且纹理像素格式有与硬件有这密切的关系。
下面我们先了解一下纹理像素的格式,主要的格式有:
RGBA8888。32位色,它是默认的像素格式,每个通道8位(比特),每个像素4个字节。
BGRA8888。32位色,每个通道8位(比特),每个像素4个字节。
RGBA4444。16位色,每个通道4位(比特),每个像素2个字节。
RGB888。24位色,没有Alpha通道,所以没有透明度。每个通道8位(比特),每个像素3个字节。
RGB565。16位色,没有Alpha通道,所以没有透明度。R和B通道是各5位,G通道是6。
RGB5A1(或RGBA5551)。16位色,每个通道各4位,Alpha通道只用1位表示。
PVRTC4。4位PVR压缩纹理格式,PVR格式是专门为iOS设备上面的PowerVR图形芯片而设计的。它们在iOS设备上非常好用,因为可以直接加载到显卡上面,而不需要经过中间的计算转化。
PVRTC4A。具有Alpha通道的,4位PVR压缩纹理格式。
PVRTC2。2位PVR压缩纹理格式。
PVRTC2A。具有Alpha通道的,2位PVR压缩纹理格式。


此外,PVR格式在保存的时候还可以采用Gzip和zlib压缩格式进行压缩,对应的保存文件为pvr.gz和pvr.ccz。经过压缩文件会更小,加载的时候使用更少的内存!虽然是转化为纹理的时候,需要解压,但对于CPU影响很小。


2.纹理缓存异步加载
我们在启动游戏和进入场景时候,由于需要加载的资源过多就会比较“卡”,用户体验不好。我们可以采用纹理缓存(TextureCache)异步加载纹理图片,TextureCache类异步加载函数如下:
virtual void addImageAsync(const std::string & filepath,
std::function< void(Texture2D *)> callback 

其中第一个参数文件路径,第二参数是回调函数。下面我们通过一个实例介绍一下纹理缓存异步加载使用,有200张小图片,加载到纹理缓存,加载过程会有一个进度显式在界面上,如图20-25所示。

 纹理缓存异步加载实例

HelloWorldScene.cpp中主要代码如下:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. bool HelloWorld::init()  
  2. {  
  3.     if ( !Layer::init() )  
  4.     {  
  5.         return false;  
  6.     }  
  7.   
  8.   
  9.     Size visibleSize = Director::getInstance()->getVisibleSize();  
  10.     Vec2 origin = Director::getInstance()->getVisibleOrigin();  
  11.     auto closeItem = MenuItemImage::create(  
  12.         "CloseNormal.png",  
  13.         "CloseSelected.png",  
  14.         CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));  
  15.   
  16.   
  17.     closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,  
  18.         origin.y + closeItem->getContentSize().height/2));  
  19.     auto menu = Menu::create(closeItem, NULL);  
  20.     menu->setPosition(Vec2::ZERO);  
  21.     this->addChild(menu, 1);  
  22.   
  23.   
  24.     _labelLoading = Label::createWithTTF ("loading...", "fonts/Marker Felt.ttf", 35);  
  25.     _labelPercent = Label::createWithTTF ("0%%", "fonts/Marker Felt.ttf", 35);  
  26.   
  27.   
  28.     _labelLoading->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 - 20));  
  29.     _labelPercent->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 + 20));  
  30.   
  31.   
  32.     this->addChild(_labelLoading);  
  33.     this->addChild(_labelPercent);  
  34.   
  35.   
  36.     _numberOfLoadedSprites = 0;  
  37.     _imageOffset = 0;  
  38.   
  39.   
  40.     auto sharedFileUtils = FileUtils::getInstance();  
  41.     std::string fullPathForFilename   
  42.                 = sharedFileUtils->fullPathForFilename("ImageMetaData.plist");               ①  
  43.   
  44.   
  45.     ValueVector vec = FileUtils::getInstance()->getValueVectorFromFile(fullPathForFilename);     ②  
  46.     _numberOfSprites = vec.size();                                          ③  
  47.     //加载纹理  
  48.     for( auto& e : vec)                                                     ④  
  49.     {   
  50.         auto row = e.asValueMap();  
  51.         auto filename = "icons/" + row.at("filename").asString();         
  52.         Director::getInstance()->getTextureCache()->addImageAsync(filename,  
  53.                 CC_CALLBACK_1(HelloWorld::loadingCallBack, this));                  ⑤  
  54.     }  
  55.     return true;  
  56. }  
  57.   
  58.   
  59. void HelloWorld::loadingCallBack(Texture2D *texture)                                ⑥  
  60. {  
  61.     ++_numberOfLoadedSprites;  
  62.     __String* str = __String::createWithFormat("%d%%",   
  63.                         (int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100));       ⑦  
  64.     _labelPercent->setString(str->getCString());                                  ⑧  
  65.   
  66.   
  67.     Size visibleSize = Director::getInstance()->getVisibleSize();  
  68.     int i = ++_imageOffset * 60;  
  69.   
  70.   
  71.     auto sprite = Sprite::createWithTexture(texture);                               ⑨  
  72.     sprite->setAnchorPoint(Vec2(0,0));  
  73.     addChild(sprite, -1);  
  74.     sprite->setPosition(Vec2( i % (int)visibleSize.width, (i / (int)visibleSize.width) * 60));  
  75.   
  76.   
  77.     if (_numberOfLoadedSprites == _numberOfSprites)                             ⑩  
  78.     {  
  79.         _numberOfLoadedSprites = 0;  
  80.     }  
  81. }  



上述代码第①行代码是获得资源目录下ImageMetaData.plist 文件全路径,ImageMetaData.plist 文件是我们定义用来描述要加载图标文件名,文件内容如下:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"   
  3.                 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
  4. <plist version="1.0">  
  5.   <array>  
  6.     <dict>  
  7.       <key>filename</key>  
  8.       <string>01-refresh.png</string>  
  9.     </dict>  
  10.     <dict>  
  11.       <key>filename</key>  
  12.       <string>02-redo.png</string>  
  13.     </dict>  
  14.     <dict>  
  15.       <key>filename</key>  
  16.       <string>03-loopback.png</string>  
  17.     </dict>  
  18.     <dict>  
  19.       <key>filename</key>  
  20.       <string>04-squiggle.png</string>  
  21.     </dict>  
  22.    … …    
  23.   </array>  
  24. </plist>    



ImageMetaData.plist 文件是属性列表文件,内部结构是数组类型,我们可以通过第②行代码FileUtils 的getValueVectorFromFile函数读入到ValueVector类型变量vec中。第③行代码_numberOfSprites = vec.size()是获得数组的长度,然后赋值给成员变量_numberOfSprites为了能够计算加载进度。
第④行代码是循环遍历数组,数组结构中的每一个元素是键值对结构,取的键值对结构语句是auto row = e.asValueMap()。然后通过语句row.at("filename").asString()从键值对对象row中取出键为filename对应的值。
第⑤行代码是调用TextureCache的addImageAsync函数实现异步加载图片缓存,HelloWorld::loadingCallBack是回调函数,this参数表示回调函数的目标对象。
第⑥行是我们定义的回调函数实现。第⑦行代码在的表达式(int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100)可以计数出加装进度,"%d%%"可以显示百分号,其中的%d是格式化输出数字。%%是输出%,前面%起到转义作用。第⑧行代码_labelPercent->setString(str->getCString())是设置进度标签_labelPercent的内容。

第⑨行代码auto sprite = Sprite::createWithTexture(texture)是通过纹理对象texture创建精灵对象。第⑩行代码if (_numberOfLoadedSprites == _numberOfSprites)是判断是否完成任务,_numberOfLoadedSprites是已经加装的图片数,_numberOfSprites是要加装的全部图片数。

 

 

更多内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
本书交流讨论网站:http://www.cocoagame.net
更多精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
欢迎加入Cocos2d-x技术讨论群:257760386


《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

京东:http://item.jd.com/11584534.html

亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

当当:http://product.dangdang.com/23606265.html

互动出版网:http://product.china-pub.com/3770734

 

《Cocos2d-x实战 C++卷》源码及样章下载地址:

源码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1 

样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

欢迎关注智捷iOS课堂微信公共平台
分享到:
评论

相关推荐

    Cocos2d-x 3.x游戏开发实战pdf含目录

    在Cocos2d-x 3.x中,有丰富的动画支持,如动作(Actions)、时间线(Timeline)等。同时,Cocos2d-x集成了Box2D物理引擎,使开发者能轻松实现物理效果,如碰撞检测、重力模拟等。 游戏中的音频管理也是不可或缺的一...

    经典版本 方便下载 源码 旧版本 3.8 官网找不到了 cocos2d-x-3.8.zip

    《cocos2d-x 3.8:经典游戏引擎源码解析》 cocos2d-x 是一个跨平台的游戏开发框架,它基于C++,同时提供了Lua和JavaScript的绑定,让开发者可以方便地在多种操作系统上创建2D游戏、演示程序和其他图形交互应用。这...

    cocos2d-x-3.1.zip

    3. **渲染引擎**:Cocos2d-x 3.1包含了强大的2D渲染引擎,能够处理精灵(Sprites)、纹理(Textures)、动画(Animations)、粒子系统(Particle Systems)等图形元素。 4. **场景管理**:使用Scene类来管理游戏的...

    Cocos2d-x实战 JS卷

    8. **网络编程**:学习如何在Cocos2d-x中实现网络通信,包括HTTP请求、WebSocket连接,以及游戏中的数据同步。 9. **音频播放**:掌握音频管理,包括背景音乐、音效的播放与控制,提升游戏体验。 10. **性能优化**...

    cocos2d-x 案例开发大全 第二章(源码)

    3. **场景和层管理**:在cocos2d-x中,游戏逻辑通常组织在不同的场景(Scene)和层(Layer)中。场景是游戏的主要容器,而层则是场景中的子容器,用于承载具体的游戏元素和逻辑。 4. **精灵(Sprite)和动画(Animation)**...

    《Cocos2d-x实战 Lua卷》源码.7z

    8. **网络通信**:如果源码包含联网功能,可以了解如何在Cocos2d-x中实现网络请求,实现多人在线游戏或同步游戏状态。 9. **性能优化**:查看源码中关于性能优化的技巧,如减少不必要的计算、利用缓存、优化渲染等...

    cocos2d-1.0.1-x-0.10.0

    在这一版本中,Cocos2d-x 提供了以下关键特性: 1. **跨平台支持**:Cocos2d-x 支持多种操作系统,包括iOS、Android、Windows、Mac OS X以及Linux,这使得开发者可以编写一次代码,然后在多个平台上部署和运行。 2...

    Cocos2d-x demo程序

    在Cocos2d-x中,开发者可以利用其强大的图形渲染能力、物理引擎、动画系统、音频处理和事件管理等功能。这个demo可能包含了以下几个关键知识点: 1. **初始化与场景管理**:Cocos2d-x 使用Scene对象来表示游戏中的...

    cocos2d-x入门讲解

    精灵是Cocos2d-x中的基本图形元素,可以理解为一个可移动、可操作的图片。动作则是控制精灵变化的一系列指令,如移动、旋转、缩放等,通过组合动作,可以实现复杂的动画效果。 五、节点树结构 Cocos2d-x采用节点树...

    cocos2d-x教程

    在cocos2d-x中,游戏逻辑被组织成一个个场景(Scene)。场景由节点(Node)组成,节点可以是精灵(Sprite)、层(Layer)、菜单(Menu)等。节点之间可以形成树形结构,通过添加、移除、布局节点来构建游戏世界。 ...

    cocos2d-x-2.1.4.zip

    2.1.4版本作为历史的一个节点,它记录了cocos2d-x发展过程中的一个重要阶段,对于开发者来说,这是一个学习和研究历史技术演进的宝贵资源。 首先,我们来了解一下cocos2d-x的核心特性。这个框架使用C++作为主要编程...

    cocos2d-x-2.2.2 中文帮助文档

    4. **场景管理**:cocos2d-x中的Scene、Layer、Node等概念构成了游戏世界的基本元素。Scene是游戏的顶级容器,Layer是场景中的分层,Node是基本的对象单位,可以包含子节点,实现复杂的游戏逻辑。 5. **精灵...

    cocos2d-x-2.1.4帮助文档

    《cocos2d-x-2.1.4帮助文档》是针对游戏开发框架cocos2d-x的一个详细参考资料,该框架是用C++编写,广泛应用于2D游戏、实验性的3D游戏以及实时渲染应用程序的开发。cocos2d-x是开源的,基于cocos2d-iphone扩展而来,...

    cocos2d-x-cocos2d-x-2.2.2.zip

    这个压缩包“cocos2d-x-cocos2d-x-2.2.2.zip”包含了cocos2d-x 的2.2.2版本,该版本是cocos2d-x发展中的一个重要里程碑,它提供了许多改进和优化,使得开发者能够更加高效地创建2D游戏和应用。 在cocos2d-x 2.2.2中...

    cocos2d-x中国象棋

    1. **对象和场景管理**:在Cocos2d-x中,游戏逻辑被组织成一系列的节点(Node),这些节点可以是游戏对象如棋子,也可以是场景(Scene)。开发者通过创建和管理这些节点来构建游戏世界。 2. **用户交互**:游戏中的...

    Cocos2d-X by Example Beginner's Guide

    1. 场景管理:Cocos2d-X中的Scene代表游戏的各个阶段或屏幕,开发者可以通过Director类来切换不同的场景,实现游戏流程的控制。 2. 动作与动画系统:Cocos2d-X提供了丰富的动作类,如移动、旋转、缩放和淡入淡出等...

    cocos2d-x默认第一个模板

    在cocos2d-x中,开发者可以使用命令行工具或可视化IDE(如Cocos Studio)来创建项目。创建后,会自动生成一个`main.cpp`文件,这是项目的入口点。在其中,`application::init()`函数初始化引擎,然后创建并运行第一...

    cocos2d-x-Introduction.zip_cocos2d_cocos2d-x

    cocos2d-x提供了多种性能优化手段,如批次绘制、纹理 atlasing、预加载机制等,确保游戏在不同设备上都能流畅运行。 十、社区支持 cocos2d-x拥有庞大的开发者社区,提供了丰富的教程、示例代码、插件和第三方库,...

    cocos2d-x版本的对对碰代码

    【cocos2d-x版本的对对碰代码】是一个基于Cocos2d-x游戏引擎实现的经典消除类游戏项目,它将原有的Cocos2d版本的对对碰游戏移植到了跨平台的Cocos2d-x框架下。Cocos2d-x是Cocos2d的C++扩展,支持iOS、Android、...

    cocos2d-x-3.2_richer(第四部分).rar

    这个压缩包“cocos2d-x-3.2_richer(第四部分).rar”包含了使用Cocos2d-x 3.2版本开发大富翁游戏项目的部分源代码,这将带我们深入理解如何在Cocos2d-x中构建一款完整的游戏。 1. **Cocos2d-x 3.2 版本特性** - ...

Global site tag (gtag.js) - Google Analytics