Cocos2d-x源码解析(1)——地图模块(2)
2014-06-19 14:40
357 查看
接上一章《Cocos2d-x源码解析(1)——地图模块(1)》
首先TMX文件本身就是XML格式,我们可以随手做一个来分析TM自身的结构。
我们可以发现,大部分的标签和属性都在每个节点的开始节点(</xxx>是结束节点)
那么我们就可以去看看 代码
我们发现cocos将xml的属性预处理到一个Map中,然后根据不同的标签名来做对应的处理。
那么我们拿layer进行举例
我们发现他将layer的信息都装进了CCTMXLayerInfo,这个类中,因此我们可以知道CCTMXLayerInfo是存储图层信息,CCTMXTilesetInfo是存储瓦片信息,CCTMXMapInfo是存储地图级别的信息。
另外,我们还注意到 pTMXMapInfo->setParentElement(TMXPropertyLayer);这句,cocos通过这样的方式来告诉下一次找到元素时,他的父节点是谁。
但是,就有一个问题,就是这些信息cocos都将他存储到CCArray中,如何能找到每个元素对应的瓦片信息呢。我们在endElement(void *ctx, const char *name)函数中找到了答案:
在地图生成的时候,就已经定义好了这个数值,因此在生成cclayer的时候快速地定位到哪个tile进行贴图。
首先TMX文件本身就是XML格式,我们可以随手做一个来分析TM自身的结构。
<?xml version="1.0" encoding="UTF-8"?> <map version="1.0" orientation="orthogonal" width="100" height="100" tilewidth="32" tileheight="32"> <tileset firstgid="1" name="210201333565" tilewidth="32" tileheight="32"> <image source="D:/project/games/cocos2d-x-2.2.2/cocos2d-x-2.2.2/template/multi-platform-cpp/Resources/210201333565.png" width="256" height="256"/> </tileset> <layer name="块层 1" width="100" height="100"> <data encoding="base64" compression="zlib"> eJztwwEJAAAMBKEL8P3zDpZDwVVTVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/AcA31NA= </data> </layer> </map>
我们可以发现,大部分的标签和属性都在每个节点的开始节点(</xxx>是结束节点)
那么我们就可以去看看 代码
void CCTMXMapInfo::startElement(void *ctx, const char *name, const char **atts) { CC_UNUSED_PARAM(ctx); CCTMXMapInfo *pTMXMapInfo = this; std::string elementName = (char*)name; std::map<std::string, std::string> *attributeDict = new std::map<std::string, std::string>(); if (atts && atts[0]) { for(int i = 0; atts[i]; i += 2) { std::string key = (char*)atts[i]; std::string value = (char*)atts[i+1]; attributeDict->insert(pair<std::string, std::string>(key, value)); } } if (elementName == "map") {
我们发现cocos将xml的属性预处理到一个Map中,然后根据不同的标签名来做对应的处理。
那么我们拿layer进行举例
else if (elementName == "layer") { CCTMXLayerInfo *layer = new CCTMXLayerInfo(); layer->m_sName = valueForKey("name", attributeDict); CCSize s; s.width = (float)atof(valueForKey("width", attributeDict)); s.height = (float)atof(valueForKey("height", attributeDict)); layer->m_tLayerSize = s; std::string visible = valueForKey("visible", attributeDict); layer->m_bVisible = !(visible == "0"); std::string opacity = valueForKey("opacity", attributeDict); if( opacity != "" ) { layer->m_cOpacity = (unsigned char)(255 * atof(opacity.c_str())); } else { layer->m_cOpacity = 255; } float x = (float)atof(valueForKey("x", attributeDict)); float y = (float)atof(valueForKey("y", attributeDict)); layer->m_tOffset = ccp(x,y); pTMXMapInfo->getLayers()->addObject(layer); layer->release(); // The parent element is now "layer" pTMXMapInfo->setParentElement(TMXPropertyLayer); }
我们发现他将layer的信息都装进了CCTMXLayerInfo,这个类中,因此我们可以知道CCTMXLayerInfo是存储图层信息,CCTMXTilesetInfo是存储瓦片信息,CCTMXMapInfo是存储地图级别的信息。
另外,我们还注意到 pTMXMapInfo->setParentElement(TMXPropertyLayer);这句,cocos通过这样的方式来告诉下一次找到元素时,他的父节点是谁。
但是,就有一个问题,就是这些信息cocos都将他存储到CCArray中,如何能找到每个元素对应的瓦片信息呢。我们在endElement(void *ctx, const char *name)函数中找到了答案:
if(elementName == "data" && pTMXMapInfo->getLayerAttribs()&TMXLayerAttribBase64) { pTMXMapInfo->setStoringCharacters(false); CCTMXLayerInfo* layer = (CCTMXLayerInfo*)pTMXMapInfo->getLayers()->lastObject(); std::string currentString = pTMXMapInfo->getCurrentString(); unsigned char *buffer; len = base64Decode((unsigned char*)currentString.c_str(), (unsigned int)currentString.length(), &buffer); if( ! buffer ) { CCLOG("cocos2d: TiledMap: decode data error"); return; } if( pTMXMapInfo->getLayerAttribs() & (TMXLayerAttribGzip | TMXLayerAttribZlib) ) { unsigned char *deflated; CCSize s = layer->m_tLayerSize; // int sizeHint = s.width * s.height * sizeof(uint32_t); int sizeHint = (int)(s.width * s.height * sizeof(unsigned int)); int inflatedLen = ZipUtils::ccInflateMemoryWithHint(buffer, len, &deflated, sizeHint); CCAssert(inflatedLen == sizeHint, ""); inflatedLen = (size_t)&inflatedLen; // XXX: to avoid warnings in compiler delete [] buffer; buffer = NULL; if( ! deflated ) { CCLOG("cocos2d: TiledMap: inflate data error"); return; } layer->m_pTiles = (unsigned int*) deflated; } else { layer->m_pTiles = (unsigned int*) buffer; } pTMXMapInfo->setCurrentString(""); }
在地图生成的时候,就已经定义好了这个数值,因此在生成cclayer的时候快速地定位到哪个tile进行贴图。
相关文章推荐
- Cocos2d-x源码解析(1)——地图模块(1)
- Cocos2d-x源码解析(1)——地图模块(3)
- Cocos2d-x源代码解析(1)——地图模块(1)
- Cocos2d-x源代码解析(1)——地图模块(3)
- 源码解析DLL自卸载无模块注入
- Android FM模块学习之四源码解析(二)
- Nginx源码解析- http模块分析
- nginx源码分析--nginx模块解析
- 【Cocos2d-x】Cocos2d-x参考案例源码解析之三:HelloWorld
- Backbone源码解析(二):Model(模型)模块
- 【Cocos2d-x】Cocos2d-x参考案例源码解析之二:TestCpp万变不离其宗Main入口点
- Android FM模块学习之四源码解析(一)
- jQuery源码解析--回调模块($.Callbacks())
- Nginx 源码分析-- 模块module 解析执行 nginx.conf 配置文件流程分析 一
- cocos2d-x:参考案例源码解析之一:Cocos2dx各个文件说明
- Android FM 模块学习之四 源码解析(1)
- thttpd源码解析 定时器模块
- 【Cocos2d-x】Cocos2d-x参考案例源码解析之一:Cocos2dx各个文件说明
- Android FM模块学习之四源码解析(四)
- Backbone源码解析(四):View(视图)模块