cocos2d-x how to read plist into an array
Asked Answered
M

4

6

i want to read a plist using cocos2d-x (c++) here is my plist:

<array>
    <dict>
        <key>x</key>
        <integer>0</integer>
        <key>y</key>
        <integer>0</integer>
    </dict>
    <dict>
        <key>x</key>
        <integer>140</integer>
        <key>y</key>
        <integer>12</integer>
    </dict>
    <dict>
        <key>x</key>
        <integer>120</integer>
        <key>y</key>
        <integer>280</integer>
    </dict>
    <dict>
        <key>x</key>
        <integer>40</integer>
        <key>y</key>
        <integer>364</integer>
    </dict>
<array>

it's basically an array of dictionary that consist of (x, y) coordinates. my original code for reading is:

NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"w%i", world] ofType:@"plist"];
NSMutableArray* points = [NSMutableArray arrayWithContentsOfFile:path];

but Now i need to translate it into cocos2d-x in c++. i've googled some article but they are all about reading plist into dictionary. i need an array.

EDIT:::

Now i've changed my plist format:

<dict>
    <key>11x</key>
    <integer>0</integer>
    <key>11y</key>
    <integer>0</integer>
    <key>12x</key>
    <integer>140</integer>
    <key>12y</key>
    <integer>12</integer>
<dict>

what should i do??? I still get the same error:

CCDictionary<std::string, CCObject*>* dict = CCFileUtils::dictionaryWithContentsOfFile(plistPath);
int x = (int)dict->objectForKey("11x");
int y = (int)dict->objectForKey("11y");

won't work. Please try it out first. see if you can read a int from the sample plist

Malcom answered 17/5, 2012 at 10:32 Comment(7)
I don't think coco2d-x support reading plist..but it support reading xml. So you can parse xml and get valuesInvariable
how? i think it supports plist and convert to a dictionary. (use FileUtil something)Malcom
aren't plist itself in xml format?Malcom
Yes plist is xml that's why I said to parse it. And I don't know about FileUtil. if i really works then post it as answer I will +1 it.Invariable
+1 your four answer for above info.Invariable
you need to try ccmutable arrayHardcastle
check Edit 2 in my answer you can try itHardcastle
H
10

Try the follwing line of code

//const char *pszPath = CCFileUtils::fullPathFromRelativePath(plistName);
//consider that file is in resource bundle..
// CCDictionary<std::string, CCObject*> *plistDictionary=CCFileUtils::dictionaryWithContentsOfFile("testplist.plist");
// CCArray *testitems = (CCArray*)plistDictionary->objectForKey("root");

EDIT

or you can try this too...

 CCDictionary<std::string, CCObject*> *plistDictionary = CCFileUtils::dictionaryWithContentsOfFile("testplist.plist");
 CCMutableArray<CCObject*> *testitems = (CCMutableArray<CCObject*>*)plistDictionary->objectForKey("root");
 CCLog("COUNT: %d", testitems->count());

EDIT-2

Try Following code in case of root is Dictionary

   var1 = atoi(valueForKey("blendFuncSource", dictionary));
    var2 = atoi(valueForKey("blendFuncDestination", dictionary));

Look Inside CCParticleSystem.cpp class you might get batter idea. check bool CCParticleSystem::initWithDictionary(CCDictionary<std::string, CCObject*> *dictionary) inside CCParticleSystem.cpp class

Regards, Nikhil

Hardcastle answered 17/5, 2012 at 10:49 Comment(11)
then how can i get each value (int)?Malcom
CCDictionary<std::string, int> point = testitems->objectAtIndex(index); but errorMalcom
each entry of the array is a dictionaryMalcom
no viable conversion from cocos2d::ccobject to ccmutabledictionary<std::string, int>Malcom
CCDictionary<string, CCObject> miniDict = testitems->objectAtIndex(index); try something like thatHardcastle
CCDictionary<std::string, CCObject*> plistDictionary=CCFileUtils::dictionaryWithContentsOfFile(plistStr.str().c_str()); CCMutableArray<CCObject*> *points = (CCMutableArray<CCObject*>)plistDictionary->objectForKey("root"); int index = (level - 1) * num_images_in_level * 5 + (image - 1) * 5 + spot - 1; CCObject* pointObj = points->getObjectAtIndex(index); CCDictionary<std::string, int>* point = (CCDictionary<std::string, int>*) pointObj;Malcom
CCDictionary<std::string, CCObject*> plistDictionary=CCFileUtils::dictionaryWithContentsOfFile(plistStr.str().c_str()); CCArray *points = (CCArray)plistDictionary->objectForKey("root"); int count = points->count();Malcom
when i access count = points->count(), error message: EXC_BAD_ACCESSMalcom
you must try CDictionary<std::string, CCObject*> plistDictionary = CCFileUtils::dictionaryWithContentsOfFile("testplist.plist"); CCMutableArray<CCObject*> *testitems = (CCMutableArray<CCObject*>)plistDictionary->objectForKey("root"); CCLog("COUNT: %d", testitems->count());Hardcastle
not working either. i even tried CCFileUtil::fullPathFromRelativePathMalcom
Hi, The CCParticle way works. but still no idea what's going on. could you dive into the code and make a conclusion on parsing plist files? since ppl might be using plists with different format. anyway this solved my problem. thanks!Malcom
I
3

See here is the link for reading a dictionary from file.
To read array I couldn't find any thing so what you can do is change your plist to

<dict> <key>root</key>
  <array>
    <dict>
        <key>x</key>
        <integer>0</integer>
        <key>y</key>
        <integer>0</integer>
    </dict>
    <dict>
        <key>x</key>
        <integer>140</integer>
        <key>y</key>
        <integer>12</integer>
    </dict>
    <dict>
        <key>x</key>
        <integer>120</integer>
        <key>y</key>
        <integer>280</integer>
    </dict>
    <dict>
        <key>x</key>
        <integer>40</integer>
        <key>y</key>
        <integer>364</integer>
    </dict>
  <array>
</dict>

Then

CCDictionary<std::string, CCObject*> *dict = CCFileUtils::dictionaryWithContentsOfFile("yourFile.plist");
CCArray *testitems = (CCArray*)dict->objectForKey("root");

Thanks to OMGPOP.

Invariable answered 17/5, 2012 at 10:56 Comment(7)
but how can i get the value (int) from the array? when i use objectatindex, it returns an ccobjectMalcom
hi, not working again, out of index even if i set the index to be within bound.Malcom
it seems the "root" does not exist. the objectForKey("root") returns NULLMalcom
if you can check I have edited the plist.. so you have to add this key as in my answerInvariable
yeah i noted that, but still that same problem. could you have a try? like reading a value x from sample plist?Malcom
Sorry I can't do anything apart this... if you get the solution do share it.. thanksInvariable
@NSMutableArrayRetain's solution is correct. please have a look. you probably need to have a look inside the ccparticlesystem.cpp file. cheersMalcom
C
2

when you read in a dict and using ObjectForKey("BLA"), you can typecast it to a CCString* like this :

    CCString* tmpStr = (CCString*)(yourDict->ObjectForKey("KEY"));
    int x = tmpStr->toInt();
Catholicize answered 29/5, 2012 at 10:37 Comment(0)
C
0

you can also use

Array* items = Array::createWithContentsOfFile("name.plist");
Cubical answered 13/11, 2013 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.