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,也不知道上面的理解是否有误,如果有高手发现错误还请指出,我会尽快作出修改。

原文地址:https://www.cnblogs.com/jjxxjnzy/p/3662302.html