cocos通过加载tiled 生成的tmx文件来生成游戏地图。本文主要分析cocos加载地图模块的源代码。
如图所看到的,地图加载模块由以上几个类组成。
对外的入口是类CCTMXTiledMap,在使用该类时。程序猿不须要知道其底层的其它类便可解析tmx文件生成地图。
那么。我们首先分析类CCTMXTiledMap是怎样调用其它类进行解析,该类的声明例如以下:
class CC_DLL CCTMXTiledMap :public CCNode { /** the map's size property measured intiles */ CC_SYNTHESIZE_PASS_BY_REF(CCSize,m_tMapSize, MapSize); /** the tiles's size property measured inpixels */ CC_SYNTHESIZE_PASS_BY_REF(CCSize,m_tTileSize, TileSize); /** map orientation */ CC_SYNTHESIZE(int, m_nMapOrientation,MapOrientation); /** object groups */ CC_PROPERTY(CCArray*, m_pObjectGroups,ObjectGroups); /** properties */ CC_PROPERTY(CCDictionary*, m_pProperties,Properties); public: /** * @js ctor */ CCTMXTiledMap(); /** * @js NA * @lua NA */ virtual ~CCTMXTiledMap(); /** creates a TMX Tiled Map with a TMXfile.*/ static CCTMXTiledMap* create(const char*tmxFile); /** initializes a TMX Tiled Map with a TMXformatted XML string and a path to TMX resources */ static CCTMXTiledMap* createWithXML(constchar* tmxString, const char* resourcePath); /** initializes a TMX Tiled Map with a TMXfile */ bool initWithTMXFile(const char *tmxFile); /** initializes a TMX Tiled Map with a TMXformatted XML string and a path to TMX resources */ bool initWithXML(const char* tmxString,const char* resourcePath); /** return the TMXLayer for the specificlayer * @js getLayer */ CCTMXLayer* layerNamed(const char*layerName); /** return the TMXObjectGroup for thespecific group * @js getObjectGroup */ CCTMXObjectGroup* objectGroupNamed(constchar *groupName); /** return the value for the specificproperty name * @js getProperty */ CCString *propertyNamed(const char*propertyName); /** return properties dictionary for tileGID */ CCDictionary* propertiesForGID(int GID); private: CCTMXLayer *parseLayer(CCTMXLayerInfo *layerInfo, CCTMXMapInfo *mapInfo); CCTMXTilesetInfo *tilesetForLayer(CCTMXLayerInfo *layerInfo, CCTMXMapInfo *mapInfo); void buildWithMapInfo(CCTMXMapInfo*mapInfo); protected: //! tile properties CCDictionary* m_pTileProperties; };
通过查看函数实现,我们发现函数
/** creates a TMX Tiled Map with a TMX file.*/ static CCTMXTiledMap* create(const char*tmxFile);
通过调用函数
/** initializes a TMX Tiled Mapwith a TMX file */ bool initWithTMXFile(const char *tmxFile);
来实现文件的解析。并创建一个CCTMXTiledMap对象返回给使用者。
boolCCTMXTiledMap::initWithTMXFile(const char *tmxFile) { CCAssert(tmxFile != NULL &&strlen(tmxFile)>0, "TMXTiledMap: tmx file should not bi NULL"); setContentSize(CCSizeZero); CCTMXMapInfo *mapInfo =CCTMXMapInfo::formatWithTMXFile(tmxFile); if (! mapInfo) { return false; } CCAssert(mapInfo->getTilesets()->count() != 0, "TMXTiledMap: Map not found.Please check the filename."); buildWithMapInfo(mapInfo); return true; }
通过看源代码。我们发现有2个重要的函数 CCTMXMapInfo::formatWithTMXFile(tmxFile)和buildWithMapInfo(mapInfo),看名字应该能知道formatWithTMXFile是解析XML文件将其结构化。buildWithMapInfo是将结构化的数据变成CCNode从而显示在游戏界面上。
接下来,我们查看CCTMXMapInfo是怎样组织数据以及怎样解析XML文件的,首先我们还是查看CCTMXMapInfo的声明
class CC_DLL CCTMXMapInfo :public CCObject, public CCSAXDelegator { public: /// map orientation CC_SYNTHESIZE(int, m_nOrientation, Orientation); /// map width & height CC_SYNTHESIZE_PASS_BY_REF(CCSize,m_tMapSize, MapSize); /// tiles width & height CC_SYNTHESIZE_PASS_BY_REF(CCSize,m_tTileSize, TileSize); /// Layers CC_PROPERTY(CCArray*, m_pLayers, Layers); /// tilesets CC_PROPERTY(CCArray*, m_pTilesets,Tilesets); /// ObjectGroups CC_PROPERTY(CCArray*, m_pObjectGroups,ObjectGroups); /// parent element CC_SYNTHESIZE(int, m_nParentElement,ParentElement); /// parent GID CC_SYNTHESIZE(unsigned int, m_uParentGID,ParentGID); /// layer attribs CC_SYNTHESIZE(int, m_nLayerAttribs,LayerAttribs); /// is storing characters? CC_SYNTHESIZE(bool, m_bStoringCharacters,StoringCharacters); /// properties CC_PROPERTY(CCDictionary*, m_pProperties,Properties); public: /** * @js ctor * @lua NA */ CCTMXMapInfo(); /** * @js NA * @lua NA */ virtual ~CCTMXMapInfo(); /** creates a TMX Format with a tmx file */ static CCTMXMapInfo *formatWithTMXFile(const char *tmxFile); /** creates a TMX Format with an XML stringand a TMX resource path */ static CCTMXMapInfo * formatWithXML(constchar* tmxString, const char* resourcePath); /** initializes a TMX format with a tmx file * @lua NA */ bool initWithTMXFile(const char *tmxFile); /** initializes a TMX format with an XMLstring and a TMX resource path * @lua NA */ bool initWithXML(const char* tmxString,const char* resourcePath); /** initializes parsing of an XML file,either a tmx (Map) file or tsx (Tileset) file */ bool parseXMLFile(const char *xmlFilename); /* initializes parsing of an XML string,either a tmx (Map) string or tsx (Tileset) string */ bool parseXMLString(const char *xmlString); CCDictionary* getTileProperties(); void setTileProperties(CCDictionary*tileProperties); /** implement pure virtual methods ofCCSAXDelegator * @js NA */ void startElement(void *ctx, const char*name, const char **atts); /** * @js NA */ void endElement(void *ctx, const char*name); /** * @js NA */ void textHandler(void *ctx, const char *ch,int len); inline const char* getCurrentString(){return m_sCurrentString.c_str(); } inline void setCurrentString(const char*currentString){ m_sCurrentString = currentString; } inline const char* getTMXFileName(){ returnm_sTMXFileName.c_str(); } inline void setTMXFileName(const char*fileName){ m_sTMXFileName = fileName; } private: void internalInit(const char* tmxFileName,const char* resourcePath); protected: //! tmx filename std::string m_sTMXFileName; // tmx resource path std::string m_sResources; //! current string std::string m_sCurrentString; //! tile properties CCDictionary* m_pTileProperties; unsigned int m_uCurrentFirstGID; };
通过查看声明 我们发现CCTMXMapInfo主要包含下面几个数据:
- TMXLayerInfo的数组,用来存放地图信息
- TMXTilesetInfo的数组,用来存放块信息
- ObjectGroups的数组
另外。CCTMXMapInfo中有几个重要的函数:
bool initWithXML(const char* tmxString, constchar* resourcePath); /** initializes parsing of an XML file,either a tmx (Map) file or tsx (Tileset) file */ bool parseXMLFile(const char *xmlFilename); /* initializes parsing of an XML string, eithera tmx (Map) string or tsx (Tileset) string */ bool parseXMLString(const char *xmlString);
这3个函数是libxml2中所须要解析xml的代理函数,分别表示标签的開始,标签的结束,标签的内容
解析xml的标签就在这几个函数中。