zoukankan      html  css  js  c++  java
  • cocos2d-x CCDictionary类学习

    前几天在看一个cocos2d的战争类游戏的时候看到了CCDictionary这个类,之前貌似没见过,就顺带这学习了,其主要数据结构为一个HashMap,可以解析一写游戏工具生成的文件,如Box2D的数据,TexturePacker的数据等。这个类看字面意思就是一个字典类,但是其解析方式先简单说说吧,这样有助于理解。其在接写plist文件的时候类似于我们解析XML文件时的dom方式,其在内存中是以树状的结构呈现的,说到这里应该就简单多了,废话就不说了直接上代码吧,在这里我先把我写的这个例子的github地址跟上吧,这样大家就可以下到plist文件

    git@github.com:jinjianxin/cocos2d-x.git

    只要下载这个里面的TestDict就可以了。在这里我们就直接贴上解析plist文件的代码吧

      1     const char * testPath = "/opt/cocos/cocos2d-x-2.2.1/projects/TestDict/Resources/BodyPlist.plist" ;
      2     const char * fullPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativeFile("BodyPlist.plist",testPath);
      3 
      4     CCDictionary *plistDic = CCDictionary::createWithContentsOfFile(fullPath);
      5 
      6     CCDictionary *metaDic = dynamic_cast<CCDictionary *>(plistDic->objectForKey("metadata"));
      7     int format = dynamic_cast<CCString *>(metaDic->objectForKey("format"))->intValue();
      8     float ptmRatio = dynamic_cast<CCString *>(metaDic->objectForKey("ptm_ratio"))->floatValue();
      9 #ifdef DEBUG
     10     CCLog("%d	%2.2f
    ",format,ptmRatio);
     11 #endif
     12 
     13     CCDictionary *bodyDic = dynamic_cast<CCDictionary *>(plistDic->objectForKey("bodies"));
     14 
     15     CCDictElement *element;
     16     CCDICT_FOREACH(bodyDic,element)
     17     {
     18         CCDictionary *test = dynamic_cast<CCDictionary *>(bodyDic->objectForKey("Head"));
     19         CCPoint point = CCPointFromString(test->valueForKey("anchorpoint")->getCString());
     20 
     21 #ifdef DEBUG
     22         CCLog("%2.2f	%2.2f
    ",point.x,point.y);
     23 #endif
     24 
     25         CCArray * fixturesList = static_cast<CCArray *>(test->objectForKey("fixtures"));
     26 
     27         if(fixturesList !=NULL)
     28         {
     29             CCObject *obj;
     30             CCARRAY_FOREACH(fixturesList,obj)
     31             {
     32                 if(obj !=NULL)
     33                 {
     34                     CCLog("success
    ");
     35                     CCDictionary *itemDict = static_cast<CCDictionary *>(obj);
     36 
     37                     if(itemDict!=NULL)
     38                     {
     39                         int filter_categoryBits = dynamic_cast<CCString *>(itemDict->objectForKey("filter_categoryBits"))->intValue();
     40                         int filter_maskBits = dynamic_cast<CCString *>(itemDict->objectForKey("filter_maskBits"))->intValue();
     41                         int filter_groupIndex = dynamic_cast<CCString *>(itemDict->objectForKey("filter_groupIndex"))->intValue();
     42                         float friction = dynamic_cast<CCString *>(itemDict->objectForKey("friction"))->floatValue();
     43                         float density =dynamic_cast<CCString *>(itemDict->objectForKey("density"))->floatValue();
     44                         float restitution =dynamic_cast<CCString *>(itemDict->objectForKey("restitution"))->floatValue();
     45                         int isSensor = dynamic_cast<CCString *>(itemDict->objectForKey("isSensor"))->intValue();
     46 
     47                         const char *fixture_type = dynamic_cast<CCString *>(itemDict->objectForKey("fixture_type"))->getCString();
     48 
     49 #ifdef DEBUG
     50                         CCLog("%d	%d	%d	%2.2f	%2.2f	%2.2f	%d
    ",filter_categoryBits,filter_maskBits,filter_groupIndex,
     51                               friction,density,restitution,isSensor);
     52 #endif
     53 
     54                         if(strcmp(fixture_type,"POLYGON") == 0)
     55                         {
     56 #ifdef DEBUG
     57                             CCLog("fixture_type = %s
    ",fixture_type);
     58 #endif
     59 
     60 #if 1
     61                             CCArray * arrayList = static_cast<CCArray *>(itemDict->objectForKey("polygons"));
     62 
     63                             if(arrayList!=NULL)
     64                             {
     65 #ifdef DEBUG
     66                                 CCLog("get arrayList success
    ");
     67 #endif
     68 #if 1
     69                                 CCObject *obj = NULL;
     70                                 CCARRAY_FOREACH(arrayList,obj)
     71                                 {
     72                                     CCArray *array = static_cast<CCArray *>(obj);
     73 
     74                                     if(array !=NULL)
     75                                     {
     76                                         CCObject *tmp;
     77                                         CCARRAY_FOREACH(array,tmp)
     78                                         {
     79 
     80                                             CCPoint point  = CCPointFromString(static_cast<CCString *>(tmp)->getCString());
     81                                             CCLog("%2.2f	%2.2f
    ",point.x,point.y);
     82                                         }
     83                                     }
     84                                 }
     85 #endif
     86                             }
     87 #endif
     88 
     89                         }
     90                         else if(strcmp(fixture_type,"CIRCLE") == 0)
     91                         {
     92 #ifdef DEBUG
     93                             CCLog("fixture_type = %s
    ",fixture_type);
     94 #endif
     95                         }
     96                         else
     97                         {
     98                             CCLog("error
    ");
     99                         }
    100 
    101                         CCArray *polygonsList = static_cast<CCArray *>(itemDict->objectForKey("polygons"));
    102 
    103                         if(polygonsList!=NULL)
    104                         {
    105                             CCLog("success
    ");
    106                         }
    107 
    108                     }
    109                     else
    110                     {
    111                         CCLog("error
    ");
    112                     }
    113 
    114                 }
    115                 else
    116                 {
    117                     CCLog("error
    ");
    118                 }
    119             }
    120         }
    121         else
    122         {
    123             CCLog("error
    ");
    124         }
    125     }

    以上就是解析的全部代码了,接下来我们可以一下解析流程:

    首先第四行的代码就是构造一个以plist文件作为参数的字典类,这个可以在其源代码里看到,其主要有三种创建方式,在这里我们用的是第三种,在这里我把它的声明贴一下:

    1 static CCDictionary* create();
    2 static CCDictionary* createWithDictionary(CCDictionary* srcDict);
    3 static CCDictionary* createWithContentsOfFile(const char *pFileName);

    这个时候我们需要把plist文件的结构列一下,但是这个文件太多了,我就不列了,代码我已经上传了,想看的就自己打开吧,在这里我们需要取出其“metadata”字段的数据,把plist文件摘抄出一部分来如下

    1 <key>metadata</key>
    2         <dict>
    3             <key>format</key>
    4             <integer>1</integer>
    5             <key>ptm_ratio</key>
    6             <real>32</real>
    7         </dict>

    这个时候我们就可以把他递归的看作一个新的plist文件,这个时候我们就可以直接取出他的字段了,第六行至第八行的代码就是完成这样一个工作,在这里的代码就不多解释了。接着往下,我们继续解析这个文件,接着我们要取出“bodies”标签的内容,需要注意的是此处我们字典的父类还是plistDic对象。接着大家仔细看一下“bodies”标签下的内容就会发现其是一个循环结构,所以我们在这里就需要遍历我们获得的字典对象,在这里我们又看到一个新的数据结构CCDictElement,这个主要是用来遍历字典类的。接着我们使用和上述一样的方法取出“anchorpoint”字段的值,接下来我们要取得“fixtures”对象的字典,在这里我们分析了下plist文件,发现它的标签是array对象,直觉告诉我们,我们需要把这个东西转化为一个数组对象。接这个我们遍历刚刚转化的数组对象。接着我们往下看,发现其又退化为了一个CCDictionary类,所以我们在强制把数组对象转化为一个CCDictionary类,按照上面的方法依次取出其key值。接着我们看到“polygons”标签的值其又变化为了一个数组,那我们在按照之前的方法,将其转化为一个数组对象,接着我们发现其在array的标签里又嵌套了一层array的标签,所以我们在这里写两层循环就可以接着出这个值了。到这个这个文件就算解析完了。

    由于本人也是在自学cocos2d-x,也不知道上面的理解是否有误,如果有高手发现错误还请指出,我会尽快作出修改。

  • 相关阅读:
    TODO C++ lambda表达式
    C++ Map实践
    【转】C++ typedef typename 作用
    C++ Vector实践
    再学引用
    设置table中的td一连串内容自动换行
    JavaScript中基本数据类型和引用数据类型的区别
    “浏览器模式”和“文档模式”之间的区别
    浏览器模式与文档模式区别
    HTML5中的data-*属性和jQuery中的.data()方法使用
  • 原文地址:https://www.cnblogs.com/jjxxjnzy/p/3662302.html
Copyright © 2011-2022 走看看