想问下,关于cocos2d 打包 资源做的游戏的资源应该怎么打包

Cocos2d-wophone中如何将资源文件打包成zip文件
Cocos2d-wophone中如何将资源文件打包成zip文件
    前置条件
  这里假定读者已经能够使用 cocos2d-wophone 进行游戏的开发,并且可以通过从硬盘读取资源文件。如果还不清楚这些的话,那么请移步到 这里
补充相关的知识。
  本文中使用的示例代码、截图等都是基于 cocos2d-x 源码中的 tests 工程的,为了在阅读本文时能够更好的明白各个操作,建议您下载
cocos2d-x的源码 ,并按照如何在WoPhone上运行tests工程这篇文章将 tests工程运行起来。
  如何操作
  对于如何让自己的代码可以从zip文件中读取相应的资源文件,操作是很简单的,只需要两个步骤。这里以 test wophone 工程为例,步骤如下:
  首先将 tests/Res 目录下的所有的资源文件打包成 TestCocos2dx.zip
文件,并且需要将该文件放到指定的目录(见第二步中示例代码)。这里为了让代码中使用资源文件时所用的参数不需要修改,需要保证 zip
文件中的目录结构如下图:
  然后在 AppDelegate 类的 applicationDidFinishLaunching 函数中添加如下代码即可:
  1#if defined(CCX_PLATFORM_WOPHONE)
  2 // set the resource zip file
  3 CCFileUtils::setResource(&TestCocos2dx.zip&);
  4#endif
  cocos2d-wophone 目前支持的几种资源文件读取方式对比
实现简单,只需要调用
CCFileUtils::setResource() 接口,通过第二个参数设置资源文件路径即可。
在打包安装程序时,很难将数据文件进行打包;  2. 资源文件未完全封闭
实现简单,只需要调用 CCFileUtils::setResource() 接口通过第一个参数设置 zip 文件的名称;  2. 打包安装程序简单,只要将
zip 文件当做数据文件打包就可以了。
资源文件未完全封闭
  多种方式并存时的调用顺序
  当在代码中,多种资源文件读取方式并存时,检查的顺序如下:
  「从 zip 文件读取」-&「从硬盘读取」
  这里需要注意的一点是,当指定的 zip 文件存在时,如果需要使用的资源文件在 zip 文件中无法找到,那么将不会再从硬盘中查找资源文件。
  WoPhone 资源文件的存放路径
  根据 CCFileUtils::setResource() 函数第二个参数值的不同,需要将资源文件放到不同的目录,列表如下:
模拟器路径
D:/Work7/NEWPLUS/TG3/APP
.so 文件同目录
开发者设定的目录
开发者设定的目录
开发者设定的目录
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
职称考试题目
招生信息考研政治
网络安全安全设置工具使用手机安全
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&为什么Cocos2D开源引擎最适合游戏创业团队?
发表于 14:40|
作者Cocos2D-X核心开发者王哲
摘要:Cocos2D-X核心开发者王哲认为,只要你是做2D游戏就应该用Cocos2D;应该根据目标平台和团队擅长的编程语言选择不同Cocos2D分支;Cocos2D及其集成的第三方库都是非GPL/LGPL的。
【由CSDN和创新工场联合举办的将于-20日在国家会议中心举办。移动开发者大会(MDCC)是中国最大规模的移动开发者顶级盛会,历来以强大讲师阵容、实用议题分享、现场活动丰富而驰名,今年也将迎来第三届MDCC盛会。】
Cocos2D-X核心开发者王哲将出席本次移动开发者大会&平台与技术&主题论坛,演讲议题为&Cocos2D游戏性能优化&。王哲将结合个人多年资深开发经验,为大家带来一场精彩的演说。
Cocos2D的稳定性、可商用型和流行程度已无需证明。目前App Store中国区付费总榜前三十名约有50%是基于Cocos2D开发的,几个月来长期如此。因此:
只要你是做2D游戏就应该用Cocos2D引擎;
根据发布目标平台和团队擅长的编程语言选择不同Cocos2D分支,开源社区尊重每位程序员自己的喜好和口味;
不用担心法律和授权费用的问题,Cocos2D及其集成的第三方库都是非GPL/LGPL的;
只要你是做2D游戏就应该用Cocos2D引擎
Cocos2D家族包含了一系列不同语言、不同渲染方案的多个分支,目前稳定成熟、有商业游戏发布的主要有三个:
Cocos2D-iPhone,用优雅的Objective-C语言进行游戏开发,最近出了JavaScript绑定,游戏只能运行于iOS设备上;
Cocos2D-X,用经典的C++进行游戏开发,加以Lua绑定和JavaScript绑定,游戏可运行于iOS、Android、 Windows Phone &8、Windows 8 Metro、BlackBerry 10、bada、MeeGo、Linux、Mac OS
X等手机和桌面系统上;
Cocos2D-XNA,用C#进行游戏开发,可运行于Windows Phone 7&8之上。
还有一个分支,虽然目前尚无大型商用游戏,但未来相当看好:
Cocos2D-HTML5,基于HTML5规范集开发,采用JavaScript语言,游戏可运行在Chrome、FireFox、IE10、Opera等支持HTML5的浏览器内。
表1 Cocos2d系列引擎对不同平台和开发语言的支持
Cocos2D系列引擎对不同平台和开发语言的支持如表1所示,注意:虽然有不同分支,但只要是在同一个大版本号1.x或2.x下面,API接口是完全一样的。
采用与开发平台自身相同的编程语言是个不错的选择;但按照目前的趋势,跨平台已经成为一个基本考虑点之一,因此选择具有跨平台能力的开发语言,会让游戏开发和运营更轻松愉快。所以开发语言的选择上,大致可以这么考虑:
系统原生语言:例如在iOS上选择Objective-C,在Windows
Phone上选择C#,开发时能很方便地集成SDK上的各种功能&原生UI框架以及ShareKit、ASIHttpRequest之类的第三方库,且易 于调试。但游戏无法跨平台,因此现阶段不是太推荐;
C++:保持高性能的同时可以跨不同平台,调试方便,但开发进度偏慢,集成部分第三方库需要一次语言转换,适合技术功底比较强的小型创业团队,在开发中小型游戏上有优势;
Lua、JavaScript等跨平台脚本:可以在运行性能和开发速度上取得一个折中,缺点是调试和集成第三方库不易,适合有一两个技术高手能驾 驭语言转换层(需要二次转换,如Java&C++&Lua),然后招聘脚本程序员大量堆逻辑的中型创业团队,而且团队里程序员越多,使用脚本 带来的增益越明显。此方案在开发大型游戏上有进度优势。在工具方面,Cocos2D和多数开源社区一样是个集市,没有建造大教堂思路下集中控制的一站式解 决方案,因此你需要从不同软件提供商手里购买针对不同使用目的的工具,基本覆盖了游戏开发过程的方方面面,比较流行的有:
CocosBuilder是目前最好的UI编辑器和动作编辑器,拥有开源免费MIT许可。在2.1版本之后加入了大家翘盼已久的时间轴动作编辑功 能。其作者Viktor Lidholt已被Zynga的Cocos2D团队收编,因此CocosBuilder很显然会是整个社区最重要的编辑器之一;
71squared的Particle Designer,必不可少的粒子编辑器,8美元一套,还不到买一份肯德基全家桶的钱;
mapeditor.org的Tilemap Editor,这个是开源免费的;
Texture Atlas打包工具如Texture Packer、Zwoptex;
SpriteHelper、LevelHelper系列。
除此之外,还有一些比较新潮但用户不多的工具,例如,让你在一个代码 编辑器里完成基于Cocos2D-X的多平台开发调试部署;还有蛋疼到碎的iTileMaps,让用户在iPad里面编辑tilemap地图,你可以买一 套送给美工同学,然后享受他想杀死你的眼神。
社区支持一直是Cocos2D引以为傲的事情。只要你礼貌地在Cocos2D-iPhone 或Cocos2D-X论坛里询问,总能得到来自世界某个角落里热心开发者的解答。除了官方论坛,国内还有39个Cocos2D
QQ群,百度文库里4534篇Cocos2D相关文档,SlideShare上196份相关PPT,CSDN下载区701份相关资源,以及海量的技术博 客,都会是你进入Cocos2D开源世界很好的学习资源。
总结Cocos2D开源引擎适合于这样的创业团队:
希望和Zynga、Glu、TinyCo、4399等使用Cocos2D的顶尖游戏公司站在同样的技术起跑线上;
希望掌握产品的每个细节,且团队中有靠谱的程序员;
希望能天马行空作出自己游戏独一无二的效果,不喜欢被闭源产品束缚作出同质化产品;
希望针对中国市场特殊性,能不费力地搞定千元智能机上的性能问题。
作者王哲,毕业于南京大学,2010年开始经营维护Cocos2D-X开源社区至今,负责《捕鱼达人》系列游戏的跨平台支持。王哲将在今年&平台与技术&主题论坛中分享Cocos2D的性能优化经验。
平台与技术主题论坛 已确认嘉宾名单(排名不分先后):
&Cocos2D游戏性能优化
&王&&&哲&&&Cocos2D-X核心开发者
&天翼开放平台服务及架构解析
&孙&&&燚&&&中国电信创新业务事业部合作拓展处处长
&如何成功实现移动云交付
&Kingsley Wood &&&亚马逊AWS布道师
&豌豆荚2.0重构经验谈
&范怀宇&&&豌豆荚2.0技术负责人
&Adobe AIR开发实践
&丁&&&然&&&斑马骑士CTO,《鲸鱼岛的冬天》制作人
&移动终端的实时推送服务
&陶建辉&&&和信创始人
&软硬整合之底层软件架构设计
&钟文昌&&&索尼移动通信架构师
&全面认识Android OS
&邓凡平&&&《深入理解Android》系列丛书作者
&Jonathan Levin& 操作系统、编程和网络设计高级顾问、培训师
讲师阵容不断更新,详情请见:
推荐阅读相关主题:
网友评论有(0)
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章2917人阅读
cocos2d(41)
在游戏的开发过程中,前期的规划 往往比 后期的“优化”更为重要!比如多分辨率适配,如果前期没有规划好,可能导致的情况是,画面只在当前测试开发机或者一部分机型正常显示。做了多套资源适配,可以使在合适的机型使用对应的图片资源,避免在高清屏幕使用低质量的图片,在低分辨率屏幕因为图片太大而浪费硬件资源。机制与策略分离,可以让你设计出简单有效的接口。模块化的设计可以让你组织好各种逻辑流程,条理分明 ~ 前期的规划工作可以有很多,一叶也在摸索之中,以使游戏的开发尽量变的简单灵活且可控。最简单的也是最容易忽略的地方,跟我们打交道最多的要数精灵了,从图片创建一个精灵,很简单的开端,将以此展开行动
本文使用 Cocos2d-3.0alpha1 版本,创建了一个 C++ 项目,介绍在 C++ 中,如何处理资源相关的内容,如果读者使用脚本,也可以参考本文中资源管理理念而忽略语言特性,你可以在 Github[^1] 上面看到本文所有源码。
也许你可称之为“命名规范”,但显然它无法表达我所想说的内容,很多人在创建精灵的时候喜欢直接使用资源名称,而没有任何定义,这是一个不好的习惯,如果游戏资源不存在,缺少,或者修改名字,如此你需要在多出引用的地方一一修改。游戏开发中的变数总是无法预料,合理的“名字系统”可以节省很多人力。
我们设定一个文件,这里名为 “Resources.h” 的文件,在其中定义所有的资源名称,在游戏开发中,尽量只&使用此处的名称,如图片名称,字体名称,声音资源等。这样做有以下好处,只是简单说几点:
如果对资源做出修改,我们可以修改此处定义,以保证同步,避免缺失,命名错误,错误引用等问题在图片名定义修改时,编译器会编译出错,并自动帮助我们 “找” 出引用的地方,方便修改由于有常量定义的缘故,我们的 IDE 会自动补全所有以定义变量名称,减少出错的可能,提高效率这个文件列表显然可以写一个如 python 脚本自动生成
使用脚本来自动生成文件常量定义显然是个行之有效的途径,这种机械式的操作交给脚本就行了,它总能出色的完成任务,首先来看看项目的 Resources 目录内容:
[Resources]~ ./tree
├── CloseNormal.png
├── CloseSelected.png
├── HelloWorld.png
├── file_list.json
├── fonts
│&& └── Marker\ Felt.ttf
└── images
├── JungleLeft.png
├── ghosts.plist
├── ghosts.png
├── grossini_family.plist
└── grossini_family.png&
以上是资源文件,那么通过脚本所生成的 “Resources.h” 文件又是什么样子的呢,脚本在 Github 仓库中可以找到(注意:资源名中最好不要有空格,以免留下“隐患”):
#ifndef _AUTO_RESOURCES_H_
#define _AUTO_RESOURCES_H_&
// search paths
static const std::vector<std::string> searchPaths = {
static const char si_CloseNormal[]
= &CloseNormal.png&;
static const char si_CloseSelected[]
= &CloseSelected.png&;
static const char sjs_file_list[]
= &file_list.json&;
static const char si_HelloWorld[]
= &HelloWorld.png&;
static const char st_MarkerFelt[]
= &Marker Felt.ttf&;
static const char sp_ghosts[]
= &ghosts.plist&;
static const char si_ghosts[]
= &ghosts.png&;
static const char sp_grossini_family[]
= &grossini_family.plist&;
static const char si_grossini_family[]
= &grossini_family.png&;
static const char si_JungleLeft[]
= &JungleLeft.png&; &
#endif // _AUTO_RESOURCES_H_
看到通过脚本,我们生成了所有文件的常量定义,这让得我们可以在游戏中任意使用,但是请注意,这里生成的文件名称是没有包含路径的,所以在定义文件之前,也自动生成了目录列表&searchPaths,顾名思义,设定了一个目录列表,以便找寻资源,我们可以在程序的开始处使用&FileUtils::getInstance()-&setSearchPaths(searchPaths);&来设定游戏的资源目录列表,这样我们就可以不用关心资源所在的目录了,你甚至可以根据需要合理的调整资源目录。
注意:通过设置 searchPaths 可以让我们不用关系资源的路径所在,那么意味着资源名称必须唯一,否则可能会出现引用问题。其次,是如果使用了多套资源方案,请注意 searchPaths 的先后顺序关系。本文暂不考虑多套资源。关于忽略资源目录的做法,如果有不同看法者,欢迎留言讨论,对我来说,忽略路径是利大于弊的 ~
以上通过脚本自动生成了文件列表,但是这显然不够,我们看到资源当中有两张&打包&资源图片(可以使用 TexturePacker 对图片资源进行打包,具有占用更小空间,优化运行效率等诸多好处,后面还会介绍此点) plist 文件。我们当然也是需要使用打包中资源的,所以脚本需要能够自动解析 plist 文件,并提取出 TexturePacker 打包的资源名称,请看如下定义,同样是自动生成在 “Resources.h”
文件之中:
////// texture //////&
// ghosts.plist
static const char si_child1[]
= &child1.gif&;
static const char si_father[]
= &father.gif&;
static const char si_sister1[]
= &sister1.gif&;
static const char si_sister2[]
= &sister2.gif&; &
// grossini_family.plist
static const char si_grossini[]
= &grossini.png&;
static const char si_grossinis_sister1[]
= &grossinis_sister1.png&;
static const char si_grossinis_sister2[]
= &grossinis_sister2.png&;
此时我们就能用以下代码来创建精灵了,都引用了资源名称定义,并且使用两种方式创建了精灵:
// 直接由图片创建精灵
auto hello = Sprite::create(si_HelloWorld);&
// 从打包资源创建精灵
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(sp_grossini_family, si_grossini_family);
auto sister = Sprite::createWithSpriteFrameName(si_grossinis_sister1);
上面我们使用两种方式创建精灵,为什么会有两种方式?也许你可以看看&&翻译的文章&其中详细的介绍了图片资源打包优化的相关细节问题,一个游戏最多的就是图片资源,优化空间最大的也是图片资源,里面详细的介绍了优化图片资源占用空间 50% 以上,如何使游戏运行内存占用优化近 50%,以 cocos2d 为例,但 cocos2d-x 同样能够适用,而且能通过脚本自动打包。 所以合理的对图片资源进行打包优化是非常有必要的。但如何处理这个流程确实不好定夺,因为不同资源的使用方式不同,因为这两种方式的存在,导致我们编写代码的逻辑不同,这需要提前预定好,所以我们考虑如下开发流程:
在游戏开发前,对所有资源打包后提供给 编写游戏人员,也就是说在写程序之前,游戏资源就已确定,那些以打包,哪些未打包都已经知道,如前面一样,通过两种方式创建精灵。但是这样的结果是,前期规定好了的,后期就无法改动,或者说很难改动,牵一发而动全身啊 ~ 这就需要加大&前期的规划&力度,以确保后期不会出现太大太多事与愿违的情形。这种情况下的&后期优化&将会非常蹩脚。况且加大前期规划的力度,可能会对整个项目的进程有所影响,如比编写人员的动工会稍缓,人力资源分配不合理。
前文提到,我们使用了 searchPaths 变量,以用忽略资源的路径,一个存在的东西,看起来好像不存在一样,我们称之为 “透明”,”透明” 在软件领域中也是重要的概念,它也强调着封装的重要性,隐藏细节的必要性。这里的资源路径就是如此,我们可以说&对于资源的使用来说,它的路径是透明的,有没有路径,路径为何?那不重要,重要的是你能通过资源名称获取想要的资源。
也许你已经发现了,我想说的不是路径问题,而是图片资源问题。对于图片资源的使用来说,它’是否是打包资源’ 应该是透明的。也既是在使用图片资源的时候,你不应该关心它是不是打包后的资源,是也好,不是也罢,这不应该影响你对资源的请求和使用。”打包” 这个过程对你来说,不存&~
图片资源类型的
“透明化” 处理
先来段代码,看看没有 “透明化” 处理时的一般使用方式:
auto jungle = Sprite::create(si_JungleLeft);&
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(sp_grossini_family, si_grossini_family);
auto sister = Sprite::createWithSpriteFrameName(si_grossinis_sister1);
以上我们看到,同样是创建精灵,&si_JungleLeft&是普通的&文件资源,而&si_grossinis_sister1&是&打包资源,这决定着两者的使用方式不同,那么怎么 “透明化” 处理呢:
// 不论图片属于 文件资源 还是 打包资源 使用方法相同
auto jungle = AssetLoader::createSprite(si_JungleLeft);
auto jungle = AssetLoader::createSprite(si_grossinis_sister1);
我们提供了一个类&AssetLoader,它有一个方法&createSprite(const std::string& name)。不论我们是不是打包资源,我们都通过这个方法来创建精灵,显然它的内部工作原理是根据图片的实际类型,动态判断并创建,之后返回,要实现这样一个功能是可行的,并且没有多复杂,实现以后。我们在使用图片资源的使用就再也用关心它是什么类型的资源了。
这也意味着你可以以一个理想的方式来管理开发流程。&图片资源可以和游戏编写同时进行,不停的添加图片资源,不停的编写游戏逻辑,而不用考虑图片是否已经优化的问题了,此时可以提供一些零散的图片,以供使用(图片命名最好还是固定),当然也可以提前把关联性比较强的图片提前打包处理,这并不影响使用,因为对程序来说,它&是透明的,”不存在”的。在后期,我们可以集中的在后期对游戏资源优化,打包处理等(关于此点,文章后面也会给出相对合理的处理流程)。
功能的实现方案与流程
在开始之前,一叶通常会将其流程在心中演算一遍,使其不会出现太大的纰漏,对于不合理的所在,可以重新拟定方案。然后实现之 ~ 要使得 AssetLoader 的 createSprite 方法完成其功能,那么它需要知道,当前请求的&图片资源&是否是&文件资源(以&文件资源&和&打包资源&区分两者),如果是,直接由前文&方式一&创建精灵返回,如果不是,则从
打包资源 里面找寻,找到就通过&方式二&创建精灵并返回,如果还没找到,就返回空指针喽 ~ 由此我们知道 AssetLoader 它内部需要完成以下功能:
能够判断一个资源是否是文件资源能够根据打包资源图片名称返回实际的 plist 文件(打包资源描述文件)和 图片文件
要完成以上功能,那就需要让 AssetLoader 知道有哪些文件资源,还要知道有哪些打包资源,我们可以在 AssetLoader 里面定义几个字典用以保存这些数据:
class AssetLoader: public Object{
static Sprite* createSprite(const std::string& name);&
static AssetLoader* getInstance();
bool init();&
bool fileExists(const std::string& filename);
std::string getTexturePlist(const std::string& name);
std::string getTextureImage(const std::string& name);&
Dictionary* _fileDict;
// 文件列表
Dictionary* _texturePlistDict;
// 打包资源到文件的映射
Dictionary* _textureImageDict;
// 打包资源plist 到图片的映射
如以上的定义实现,它有三个字典,&_fileDict&的 key 保存着所有文件资源,value 保存文件资源的&编号&,这样我们就能够随时判断一个图片是否是文件资源了。_texturePlistDict&的 key 保存着打包资源的名称,value 保存打包资源所在 Plist 文件的编号,通过它我们能通过打包资源获取到它
Plist 所在的文件。&_textureImageDict&也是类似,key 保存打包资源名称,value 保存打包资源所在的真实 图片文件的引用。
功能已经定义完毕,现在的问题是我们如何去为这几个字典填充数据?显然程序初始化手动填充不靠谱,前文的文件名等信息都已经是自动定义了,此处我们当然也希望有一个方案&自动填充&了。这里的做法是,在使用 python 生成资源定义的时候,同时生成一个 json 文件,这个文件里面包含了所有此处字典中所需要的数据,然后 AssetLoader 初始化的时候读取这个 json 文件,以完成自动填充数据的功能。先来看看自动生成的
json 文件长什么样纸:
题外话:使用 json 来存储这样一个中转的数据格式是最后定下来的方案,设计之初考虑过几种方案,比如想到可以用一个 sqlite 数据来保存各种数据,这样数据的操作就非常统一,对后期的数据统计分析也会非常方便,曾与朋友 子龙山人 讨论过这之间的详细细节,以及各种实现方案的利弊分析。使用 sqlite 的好处是更为灵活,后期扩展功能会非常方便,适合稍微大点的项目,但是如果一个项目本身没有使用 sqlite 数据库,如果为这里的方案而硬添加一个扩展库实现 sqlite,可能就会非常的不友好,不通用。
&file_name&: [
&CloseNormal.png&,
&CloseSelected.png&,
&file_list.json&,
&HelloWorld.png&,
&Marker Felt.ttf&,
&ghosts.plist&,
&ghosts.png&,
&grossini_family.plist&,
&grossini_family.png&,
&JungleLeft.png&
&file_index&: [
&1&, &2&, &3&, &4&, &5&, &6&, &7&, &8&, &9&, &10&
&texture_name&: [
&child1.gif&,
&father.gif&,
&sister1.gif&,
&sister2.gif&,
&grossini.png&,
&grossinis_sister1.png&,
&grossinis_sister2.png&
&texture_plist&: [
&6&, &6&, &6&, &6&, &8&, &8&, &8&
&texture_image&: [
&7&, &7&, &7&, &7&, &9&, &9&, &9&
以上是自动生成的 json 数据文件内容,为了在这里展示,做了点格式化和缩进,更为友好一点。通过&file_name&和&file_index&可以创建文件资源列表字典,通过&texture_name&和&texture_plist&可以创建打包资源和文件资源之间的映射,&texture_image&也是同样。
file_name 包含了所有文件资源,file_index 为文件资源做了编号,这两个数据项的个数是相同的。 texture_name 定义了所有打包资源的定义,texture_plist 和 texture_image 则保存了 打包资源所在的 plist 文件和图片文件的引用,它们的数据项个数也是相同的。只要保证这里生成的内容没有错误,那么我们就正确的将其填充到 AssetLoader 的字典里面,以实现想要的功能。
为什么数据会长这个样子?一叶本来的设计 json 文件,多层嵌套更具描述性(各种对象,各种属性,一目了然),但是发现 解析的时候稍显麻烦,在 新版 cocos2d-x 的 gui 库中,已经封装好了一些常用的 json 解析功能,本着&拿来注意(尽可能的寻找可用的资源来简化自身的流程) 的思想,为使解析过程简单,所以数据格式就定义成那个样子了 - =。现在只是用了五个数组(更平面化的数据组织,像是数据库表),保存所有数据。只能说,这样做是为了迎合代码的编写,让本来复杂的
json 解析过程变得更为简单。现在看来,但到也简单清晰,看看填充字典的关键代码实现(如果有其它更好的方式,修改也不麻烦,修改生成的数据格式,再修改代码中数据的填充方法就行了):
JsonDictionary *jsonDict = new JsonDictionary();
String* fileContent = String::createWithContentsOfFile(sjs_file_list);
jsonDict->initWithDescription(fileContent->getCString());&
DictionaryHelper* dicHelper = DICTOOL;&
_fileDict = Dictionary::create();
int file_idx = dicHelper->getArrayCount_json(jsonDict, file_name);
for (int i = 0; i < file_idx; i++){
std::string name = dicHelper->getStringValueFromArray_json(jsonDict, file_name, i);
std::string index = dicHelper->getStringValueFromArray_json(jsonDict, file_index, i);
_fileDict->setObject(String::create(index), name);
log(&file count: %d&, file_idx);&
_texturePlistDict = Dictionary::create();
int texture_idx = dicHelper->getArrayCount_json(jsonDict, texture_name);
for (int i = 0; i < texture_idx; i++){
std::string name = dicHelper->getStringValueFromArray_json(jsonDict, texture_name, i);
std::string plist = dicHelper->getStringValueFromArray_json(jsonDict, texture_plist, i);
_texturePlistDict->setObject(String::create(plist), name);
log(&texture count: %d&, texture_idx);&
_textureImageDict = Dictionary::create();
for (int i = 0; i < texture_idx; i++){
std::string name = dicHelper->getStringValueFromArray_json(jsonDict, texture_name, i);
std::string image = dicHelper->getStringValueFromArray_json(jsonDict, texture_image, i);
_textureImageDict->setObject(String::create(image), name);
CC_SAFE_DELETE(jsonDict);
这里能看到一些陌生的内容&JsonDictionary、DictionaryHelper类型和其操作方式,这里的使用方法不是本文的重点,有兴趣的朋友看看源码实现。以很简洁的方式,填充了我们需要的字典数据内容。有了这些字典数据,我们就很容易的判断一个图片是否是文件资源了,如果是打包资源,也能够很容易找出打包资源所在的 Plist 文件和 图片文件,最后看一下&createSprite&方法的实现:
Sprite* AssetLoader::createSprite(const std::string& name){
if (AssetLoader::getInstance()->fileExists(name)){
return Sprite::create(name);
log(&create sprite: %s&, name.c_str());
std::string plistfile = AssetLoader::getInstance()->getTexturePlist(name);
std::string imagefile = AssetLoader::getInstance()->getTextureImage(name);
log(&plist: %s, image: %s&, plistfile.c_str(), imagefile.c_str());
if (plistfile != && && imagefile != &&){
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistfile, imagefile);
return Sprite::createWithSpriteFrameName(name);
return nullptr;
至此我们便完成了&图片资源类型的 “透明化” 处理&。这样一个解决方案,很好的解决了在开发过程中图片资源的管理过程,后期优化,都不冲突。能够通过此提供一个较为合理的开发流程。 本文所使用的源码,脚本等都可以在 Github 上面找到 『』,但是要清楚,我这里提供的只是按照我这种流程下来的一种实现而已,对于程序本身而言,也还有很多可以改进的所在
~ 思路同样,每个人实现的具体细节可能不一样,不论你使用 C++ 还是脚本语言,都不影响你 “透明化” 图片资源类型。
如何优雅的管理游戏资源
我们解决了一些问题,提供了一些解决方案,但总有更多的问题等着我们去解决,更多的优秀解决方案,好的工作模式,处理流程。我们会把开发中一些&变动&的所在找寻出来,对它灵活的处理,使它能够适应各种不同的&险恶环境。哪些是不变的,哪些是容易变动的,尽量做到&以不变应万变。现在新的问题和需求又来了,哈
继续前文内容,我们可以使用 AssetLoader 来加载图片资源,创建精灵,实现游戏玩法逻辑等。但是我们通常会在一个场景进入时就预先缓存所有图片资源(声音资源亦是同样),甚至在游戏开始时,预先加载所有的图片资源,以&保证游戏画面的流畅性。如果没有预先缓存图片资源,那么在游戏中用到的时候,实时加载可能&会使游戏画面卡顿,这不是我们想看到的结果。如果一个游戏不大,资源总和也没多少,那么可以直接在游戏开始时全部加载完毕,这种情况处理起来比较简单,直接把所有资源加载就可以了。但是如今的游戏动辄几十兆,几百兆,显然游戏资源一次性加载是不科学的,这时我们可以分场景,在加载一个场景的时候,清空前一个场景所使用的图片缓存资源,然后预先加载当前场景的游戏资源,以达到最优的内存占用。
通常我们都是人为的,定义了一个方法在开始场景前做一些准备工作,清空缓存,预加载游戏资源,如这里有一个需要预加载的资源列表,而前文我们提到,在游戏开发的过程中,我们的图片资源可能会有所改动,这就需要我们去&人为的同步去手动维护这个列表,而这样的工作费时费力,还容易出现很多错误,如果我们能够把这一步的操作自动化,根据实际情况生成其列表,并且列表资源的加载顺序也是做过优化的(根据文件大小,或者分辨率大小,优先加载大的资源,使游戏减少因占用内存过多而崩溃的可能性),那将使我们能有&更多的精力花在更值得的地方。如果结合到本文之前的实现方案就是,在开始一个场景时,我们对
AssetLoader 做一个标记,在这个标记之后所请求的图片资源都是当前场景的资源,我们可以在内部将其记录下来,以任何方式都行,这样我们就能够非常容易的收集并生成当前场景所使用的图片资源了。如果我们将这个列表做成动态可维护的,自动记录以便下次运行时预先加载,这样一种实现从逻辑上来说时可行。如何优雅得管理游戏资源?但是实现比&优雅&更重要,在实现的过程中,尽量使开发变得简单,流程变得清晰,也是一叶努力的方向 ~
以上只是对预加载资源列表的动态维护,提供了一个简单的思路,其中还有很多细节值得推敲。但我想实现这样一种流程对游戏的开发是非常有帮助的,对于这个部分的内容,一叶还没有给出一个具体的实现方案,但将继续之前的流程往下实现,并分享在 Github 上面,同时你也可以参与进来。也算是在这里集思广益,如果你有什么好的想法,对本文实现有什么改进,都可以一起交流。如果你遇到了相同的问题,也可以说说你是怎么处理这些问题的,欢迎分享 ~
[^1]: 本文源码 Github 仓库地址:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:215727次
积分:3449
积分:3449
排名:第7759名
原创:105篇
转载:187篇
(3)(9)(7)(1)(1)(3)(3)(6)(5)(2)(1)(10)(11)(9)(12)(4)(9)(3)(4)(1)(2)(3)(3)(25)(11)(5)(3)(9)(15)(1)(1)(2)(5)(6)(17)(38)(27)(2)(12)(1)(2)(1)}

我要回帖

更多关于 cocos2dx 打包apk 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信