粒子编辑器必须要有一个保存粒子文件的功能,cocos2d-x使用plist来保存粒子文件(这是苹果的一种基于xml的文件格式,也适用于动画等)
于是我查看了cocos2d-x里面加载plist文件的代码,它是先把plist加载到一个CCDictionary类中,然后在这个类里面方便地通过key-value来获取相应的信息
 1 CCParticleSystem.cpp
 2     m_sPlistFile = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(plistFile);
 3     CCDictionary *dict = CCDictionary::createWithContentsOfFileThreadSafe(m_sPlistFile.c_str());
 4
 5 CCDictionary.cpp
 6 CCDictionary* CCDictionary::createWithContentsOfFileThreadSafe(const char *pFileName)
 7 {
 8     return ccFileUtils_dictionaryWithContentsOfFileThreadSafe(pFileName);
 9 }
10
11 CCFileUtilsCommon_cpp.h
12 CCDictionary* ccFileUtils_dictionaryWithContentsOfFileThreadSafe(const char *pFileName)
13 {
14     CCDictMaker tMaker;
15     return tMaker.dictionaryWithContentsOfFile(pFileName);
16 }
17
18 CCFileUtilsCommon_cpp.h
19     CCDictionary* dictionaryWithContentsOfFile(const char *pFileName)
20     {
21         m_eResultType = SAX_RESULT_DICT;
22         CCSAXParser parser;
23
24         if (false == parser.init("UTF-8"))
25         {
26             return NULL;
27         }
28         parser.setDelegator(this);
29
30         parser.parse(pFileName);
31         return m_pRootDict;
32     }
33
34
35 bool CCSAXParser::parse(const char *pszFile)
36 {
37     bool bRet = false;
38     unsigned long size = 0;
39     char* pBuffer = (char*)CCFileUtils::sharedFileUtils()->getFileData(pszFile, "rt", &size);
40     if (pBuffer != NULL && size > 0)
41     {
42         bRet = parse(pBuffer, size);
43     }
44     CC_SAFE_DELETE_ARRAY(pBuffer);
45     return bRet;
46 }
47
48
49 bool CCSAXParser::parse(const char* pXMLData, unsigned int uDataLength)
50 {
51     /*
52      * this initialize the library and check potential ABI mismatches
53      * between the version it was compiled for and the actual shared
54      * library used.
55      */
56     LIBXML_TEST_VERSION
57     xmlSAXHandler saxHandler;
58     memset( &saxHandler, 0, sizeof(saxHandler) );
59     // Using xmlSAXVersion( &saxHandler, 2 ) generate crash as it sets plenty of other pointers...
60     saxHandler.initialized = XML_SAX2_MAGIC;  // so we do this to force parsing as SAX2.
61     saxHandler.startElement = &CCSAXParser::startElement;
62     saxHandler.endElement = &CCSAXParser::endElement;
63     saxHandler.characters = &CCSAXParser::textHandler;
64
65     int result = xmlSAXUserParseMemory( &saxHandler, this, pXMLData, uDataLength );
66     if ( result != 0 )
67     {
68         return false;
69     }
70     /*
71      * Cleanup function for the XML library.
72      */
73     xmlCleanupParser();
74     /*
75      * this is to debug memory for regression tests
76      */
77 #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA)
78     xmlMemoryDump();
79 #endif
80
81     return true;
82 }

通过上面的代码可以看到,CCDictMaker通过调用CCSAXParser 这个类来进行plist文件的读取和解析,也就是 parse函数,然后生成一个CCDictionary
通过CCSAXParser 自己的startElement和endElement来对plist进行解析,然后插入到CCDictionary的哈希中,上层调用valueforkey即可获取对应的值
但说了这么多,我们如何保存呢?cocos2d-x提供了怎样的接口给我们进行保存呢?
查阅CCDictionary这个类,发现与valueforkey有那么点对应关系的,也就setObject这个函数,但这个函数只是把Object插入到CCDictionary本身的哈希中而已,并没有保存到plist,所以这里CCDictionary这个类跟plist唯一的联系仅仅只是从plist中解析,获取数据而已。
那么我们只能把目光转移到生成CCDictionary的CCDictMaker 这个类来了,CCDictionary 是由CCDictMaker调用CCSAXParser 生成的,那么CCDictMaker 可有提供保存到plist的方法?答案还是没有!
最后到了CCSAXParser这个类,只能看到,他调用xmlSAXUserParseMemory函数来将plist文件加载进来,至于xmlSAXUserParseMemory函数,那是在libxml/parser.h这个头文件中。
随后又查看了大量代码,从头到尾都没有保存plist文件的代码,至于CCUserDefault这个类,仅仅只是将数据保存在一个默认的xml文件中。
到了这里,也就不指望cocos提供什么接口了,直接查看粒子系统的plist文件,然后,根据其格式,自己实现一个plist类,用来保存粒子系统到plist文件。
plist文件格式大致如下,第一行是xml头,包含xml版本和字符编码
第二行是文档类型,"-//Apple//DTD PLIST 1.0//EN"是它的pubid "http://www.apple.com/DTDs/PropertyList-1.0.dtd"是它的sysid
第三行是plist的根节点,有version属性,下面有一个子节点dict,该子节点下面存放粒子系统的所有属性值
每个值由两个节点来表示,一个key节点,紧跟着还有一个value节点来表这个key的值,value节点有以下几种类型:<real>表示浮点数,<integer>表示整型,<string>表示字符串,<array>表示数组
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>angle</key>
<real>270</real>
<key>angleVariance</key>
<real>0.0</real>
......
</dict>
</plist>

关于xml的操作,之前用过CMarkUpSTL,tinyxml,这两个用得比较熟,但cocos用的是libxml,也只能去学习一下libxml
这是官网地址http://www.xmlsoft.org/
还有相关example的地址http://www.xmlsoft.org/examples/testWriter.c
在项目中实现一段如下的测试代码来保存plist
 1 //创建test.plist文件
 2 m_Writer = xmlNewTextWriterFilename(plist, 0);
 3
 4 //设置编码为utf-8并开始文档
 5 xmlTextWriterStartDocument(m_Writer, NULL, "UTF-8", NULL);
 6 //设置文档类型
 7 xmlTextWriterWriteDTD(m_Writer, BAD_CAST "plist", BAD_CAST "-//Apple//DTD PLIST 1.0//EN", BAD_CAST "http://www.apple.com/DTDs/PropertyList-1.0.dtd", NULL);
 8 //根节点为plist,version属性为1.0
 9 xmlTextWriterStartElement(m_Writer, BAD_CAST "plist");
10 xmlTextWriterWriteAttribute(m_Writer, BAD_CAST "version", BAD_CAST "1.0");
11
12 //dict节点
13 xmlTextWriterStartElement(m_Writer, BAD_CAST "dict");
14
15 //写入测试数据
16 xmlTextWriterWriteElement(m_Writer, BAD_CAST "key", BAD_CAST "key1");
17 xmlTextWriterWriteElement(m_Writer, BAD_CAST "real", BAD_CAST "key1");
18
19 //写入Base64数据
20 xmlTextWriterStartElement(m_Writer, BAD_CAST "Texture");
21 xmlTextWriterWriteBase64(m_Writer, "abcdefghij", 0, 12);
22 xmlTextWriterEndElement(m_Writer);
23
24 //结束并保存
25 xmlTextWriterEndDocument(m_Writer);

查看保存后的plist文件,发现内容是正确的,但既无缩进,又无回车,所有的代码都被写在一行,难看之极,谷歌之,需要在打开文档之前加入xmlKeepBlanksDefault(0);加了进去也毫无效果,那便算了,反正plist文件一般也是只用不看,有时间看一下libxml的源码再研究下吧

转载于:https://www.cnblogs.com/ybgame/archive/2012/07/24/2606107.html

特效编辑器开发手记2——cocos2d-x粒子系统的plist文件相关推荐

  1. cocos2d 使用TexturePacker制作plist文件

    转自:https://blog.csdn.net/chiyiw/article/details/38170573 上一篇提到plist文件在cocos2d中的使用,那么如何制作plist文件呢? 一. ...

  2. 第10节_我的日记本开发手记(10)——使用自定义图标字体

    各位朋友大家好,这小结我们主要实现绘制自己的图标字体,像使用字体那样使用我们的小图标,不但可以调整大小,而且可以调整颜色,下看一下最终效果,最终效果如图1所示. 一.FontCreatorPortab ...

  3. DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之1: 开场白

    在开场白之前的说明: 这是"DirectX 9.0c游戏开发手记"的第一部分,叫做"'龙书'第二版学习笔记",讲的是我做"龙书"第二版(原名 ...

  4. 《基于Qt的VR编辑器开发》(Yanlz+Unity+SteamVR+5G+AI+VR云游戏+Qt+编辑器+跨平台+人机交互+触发事件+立钻哥哥+==)

    <基于Qt的VR编辑器开发> <基于Qt的VR编辑器开发> 版本 作者 参与者 完成日期 备注 YanlzFramework_Qt_V01_1.0 严立钻 2019.09.04 ...

  5. Effect Exporter:一款 2D3D 特效编辑器插件,专为 Cocos Creator 深度定制

    随着 Cocos Creator 3.x 版本的发布,Cocos Creator 的 3D 功能更加完善.开发者 Oreo大魔王 着手制作了一款支持 Shader 2D&3D 的特效编辑器插件 ...

  6. HoloLens开发手记 - HoloLens shell概述 HoloLens shell overview

    使用HoloLens时,shell是由你周围的世界和来自系统的全息图像构成.我们将这种空间成为混合世界(mixed world). shell包含了一个可以让你将全息图像和应用放置在世界中的开始菜单( ...

  7. HoloLens开发手记-硬件细节 Hardware Detail

    微软HoloLens是世界第一款完全无线缆的全息计算机.通过在新方式上赋予用户的全息体验,HoloLens重新定义了个人计算(Personal Computing).为了将3D全息图形固定到你周围的真 ...

  8. HoloLens开发手记-配置开发环境 Install the tools

    随着Build 2016开发者大会的结束,HoloLens开发包也正式开放下载.Hololens没有独立的SDK,开发特性被集成到最新的Visual Studio Update 2中.如果你没有Hol ...

  9. HoloLens开发手记-全息Hologram

    全息 Hologram HoloLens使我们可以通过周边世界的光线和声音来创建全息场景和物体,使得它们像真实物体那样.全息场景能够响应你的凝视.手势和语音指令,同时还会和你周边世界的表面交互.借助全 ...

  10. 开发手记之实现web.config的快速配置(转载)

    开发手记之实现web.config的快速配置 开发手记之实现web.config的快速配置 作者:Anytao 问题简述: 在Web开发中,对web.cofig进行配置是非技术人员无法胜任的工作,但是 ...

最新文章

  1. fflush函数的深入理解
  2. spring-aop入门
  3. 在if里赋值要注意=和==的优先级,==优先于=
  4. spark指定python版本_如何将正常的Python应用程序正确转换为PySpark版本
  5. java display.getdefault()_java基础(十一 )-----反射——Java高级开发必须懂的
  6. 单片机到底是不是嵌入式?
  7. JAVA设计模式 - 创建型模式总结
  8. Linux中ftp密码输错无响应,psftp登陆输入正确用户名和密码后无响应解决办法
  9. 捕捉ctrl+c信号,并进行操作(C++实现)
  10. Linux网络端口命名规则,一致性网络设备命名
  11. 【好】Paxos以及分布式一致性的学习
  12. 3DEXPERIENCE ENOVIA
  13. 贝叶斯法则与先验概率,后验概率
  14. 南宁市计算机技术专业学校,南宁电脑技术学校有哪些
  15. php简单的商城系统,DouPHP轻量级商城管理系统
  16. java 风的角度转风向
  17. 202112-3 登机牌条码(50分)不知道错哪了
  18. cityengine规则建模实例
  19. Vcruntime140.dull.丢失解决方法
  20. Linux-FrameBuffer双缓冲机制显示图像

热门文章

  1. web端访问远程桌面
  2. java netbeans教程_Netbeans下载安装教程教程
  3. 大学最应该学习的 5 门课, 毕业后大厂 Offer 直接拿到手软!
  4. 留言板 HTML5代码
  5. Python终端显示彩色字符(封装了Colored类)
  6. Mysql数据库存储内存调整与优化
  7. Python项目部署到Docker的完整过程
  8. 【软件资源】MATLAB 7.0 安装教程
  9. 头像+壁纸微信小程序源码
  10. ofo容器pass架构分享