zoukankan      html  css  js  c++  java
  • cocos2d-x 2.2.6 之 .xml文件数据读取

      在编写读取.xml文件的功能时,参考网上的资料各种问题,所以不才写出以下测试用例,供程序新人作为参考使用吧。

    (1) 创建UTF-8格式的.xml,命名为Item.xml,数据如下(已加注释,如果若要使用,请去掉注释):

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Item>
            <ItemId>1</ItemId>              // 物品ID
            <ItemType>1</ItemType>            // 物品类型:装备,材料,消耗品
            <Name>天马流星锤</Name>            // 物品名字
            <ItemState>你想砸谁,就砸谁</ItemState>   // 物品描述
            <power>10</power>               // 力量加成
            <useLevel>10</useLevel>           // 使用最小等级限制
            <StrengthLev>10</StrengthLev>        // 强化最大等级限制
            <Speed>1.0</Speed>              // 速度加成
            <price>300</price>              // 出售价格
        </Item>
        <Item>
            <ItemId>3</ItemId>
            <ItemType>1</ItemType>
            <Name>青龙炎月刀</Name>
            <ItemState>听着名字就霸气</ItemState>
            <power>10</power>
            <useLevel>20</useLevel>
            <StrengthLev>30</StrengthLev>
            <Speed>3.0</Speed>
            <price>600</price>
        </Item>
    </Root>

    (2) 接下来,创建头文件,如XmlItem.h,代码如下:

    #ifndef __XML_ITEM_H__
    #define __XML_ITEM_H__
    
    #include "cocos2d.h"
    #include "support/tinyxml2/tinyxml2.h"
    
    USING_NS_CC;
    using namespace std;
    
    /*
    解析物品文件:Item.xml
    */
    
    // 物品
    typedef struct sItem
    {
        int Id;                // ID
        int type;              // 类型:装备,材料,消耗品
        string name;           // 名字
        string state;          // 描述
        int useMinLev;         // 使用最小等级限制
        int StrengthMaxLev;    // 强化最大等级限制
        int power;             // 力量加成
        int speed;             // 速度加成
        int sprice;            // 价格    
    }ITEMDATA;
    
    // 物品数据类
    // 编写的缘故:是由于个人已经习惯使用std::map来存储数据,然而鉴于cocos2d-x的内存管理机制且推荐cocos2d-x自带的CCDictionary进行
    // 存储,但是CCDictionary::setObject(CCObject* pObject, intptr_t key)使用CCObject* pObject对象,所以该类要继承CCNode
    class Item : public cocos2d::CCNode { public: Item(); void CleanItemData(); public: ITEMDATA data; }; // 文件解析类 class XmlItem : public cocos2d::CCNode { public: XmlItem(); ~XmlItem(); static XmlItem* GetInstance(); void AnalyticItemXml(const char* fileName); // 解析Item.xml文件             private: static XmlItem* m_pInstance; CCDictionary* m_pDicItem; }; #endif

    (3) 剩下的不用多说,来编写XmlItem.cpp,代码如下:

    #include "XmlItem.h"
    
    /////// Item
    Item::Item()
    {
        CleanItemData();
    }
    
    void Item::CleanItemData()
    {
        memset(&data,0x00,sizeof(data));
    }
    
    //////文件解析
    XmlItem* XmlItem::m_pInstance = NULL;
    XmlItem::XmlItem()
    {
        m_pDicItem = CCDictionary::create();
        m_pDicItem->retain();    // 需要添加,否则会导致崩溃,不信,可以注释掉试试  
    }
    
    XmlItem::~XmlItem()
    {
        CC_SAFE_DELETE(m_pDicItem);
    }
    
    XmlItem* XmlItem::GetInstance()
    {
        if(m_pInstance == NULL)
        {
            m_pInstance = new XmlItem();
        }
        return m_pInstance;
    }
    
    void XmlItem::AnalyticItemXml( const char* fileName )
    {
        std::string filepath = CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName);
        tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();
        tinyxml2::XMLError errorId = pDoc->LoadFile(filepath.c_str());
        if(errorId != 0)
        {
            CCLOG("xml anlyatic error: %s",fileName);
            return;
        }
    
        // 获取根元素
        tinyxml2::XMLElement *pElement = pDoc->RootElement();
        // 获取第一个子节点
        tinyxml2::XMLElement *rootElement = pElement->FirstChildElement();
        
        while(rootElement != NULL)
        {
            Item* pItem = new Item();
            // 获取节点的子级
            tinyxml2::XMLNode *pCurNode = rootElement->FirstChild();
            while(pCurNode != NULL)
            {
           // 查阅资料说,使用pCurNode->ToElement->GetText() 这样不安全,会导致内存泄露,但至今仍没有找到更好的方法,见谅
                if(!strcmp(pCurNode->Value(),"ItemType"))
                    pItem->data.type = atoi(pCurNode->ToElement()->GetText());
                else if(!strcmp(pCurNode->Value(),"ItemId"))
                    pItem->data.Id = atoi(pCurNode->ToElement()->GetText());
                else if(!strcmp(pCurNode->Value(),"Name"))
                    pItem->data.name = pCurNode->ToElement()->GetText();
                else if(!strcmp(pCurNode->Value(),"ItemState"))
                    pItem->data.state = pCurNode->ToElement()->GetText();
                else if(!strcmp(pCurNode->Value(),"power"))
                    pItem->data.power = atoi(pCurNode->ToElement()->GetText());
                else if(!strcmp(pCurNode->Value(),"price"))
                    pItem->data.sprice = atoi(pCurNode->ToElement()->GetText());
    
                // 获取该节点的下一子级
                pCurNode = pCurNode->NextSibling();
            }
            m_pDicItem->setObject(pItem,pItem->data.Id);
    
            // 进入下一个节点
            rootElement = rootElement->NextSiblingElement();
        }
    }

    如果大家有什么更好的方法,希望给其建议,谢谢大家。

  • 相关阅读:
    python 类型注解
    python 装饰器
    python 高阶函数、柯里化
    python 生成器函数
    python 递归和匿名函数
    Python 函数返回值、作用域
    Python 练习题总结(待续)
    基于 K8S 集群安装部署 istio-1.2.4
    基于 kubeadm 部署 kubernetes(v1.17.0) 集群
    Gitlab 重置 root 密码
  • 原文地址:https://www.cnblogs.com/SkyflyBird/p/5046378.html
Copyright © 2011-2022 走看看