Forum > C++ > Loading objects from TMX files

Loading objects from TMX files

By 3DModelerMan Posted 2012-07-27 00:44 Comments 15
3DModelerMan
  • Posts: 23

I’m trying to load objects that I’ve placed in my TMX map files. I need to get their type, and their position. And I also need to get properties from them (like sprite filenames, settings, etc). The CCTMXObjectGroup only has a method returning a CCArray*, but what is it filled with? Is it a bunch of CCDictionary objects? And if that’s it, what keys do I use to access the position, and the type?

3DModelerMan
  • Posts: 23

#1 RE: 2012-07-27 20:55

Anyone?

GMTDev
  • Posts: 205
  • Location: Vancouver, Canada

#2 RE: 2012-07-27 21:53

Something like this:

    CCTMXObjectGroup *objectsGroup = m_Map->objectGroupNamed("Object Layer 1");
    CCAssert(objectsGroup != NULL, "'Objects' object group not found");

    CCMutableArray *m_pObjects;
    m_pObjects = objectsGroup->getObjects();

    float x, y, x2, y2;
    CCString *name, *type_name;
    ObjectItemInfo *obj;
    int itemNo, iVals[5], iLevel;

    if (m_pObjects && m_pObjects->count() > 0)
    {
        CCMutableArray::CCMutableArrayIterator it;

        for (it = m_pObjects->begin(); it != m_pObjects->end(); ++it)
        {
            name = (*it)->objectForKey(std::string("name"));
            type_name = (*it)->objectForKey(std::string("type"));
            x = (*it)->objectForKey("x")->toFloat();
            y = (*it)->objectForKey("y")->toFloat();
            x2 = x+(*it)->objectForKey("width")->toFloat();
            y2 = y+(*it)->objectForKey("height")->toFloat();

            memset( iVals, 0, sizeof(int)*5 );
            if( (*it)->objectForKey("i0") )
                iVals[0] = (*it)->objectForKey("i0")->toInt();
            if( (*it)->objectForKey("i1") )
                iVals[1] = (*it)->objectForKey("i1")->toInt();
            if( (*it)->objectForKey("i2") )
                iVals[2] = (*it)->objectForKey("i2")->toInt();
            if( (*it)->objectForKey("i3") )
                iVals[3] = (*it)->objectForKey("i3")->toInt();
            if( (*it)->objectForKey("i4") )
                iVals[4] = (*it)->objectForKey("i4")->toInt();

            iLevel=0;
            if( (*it)->objectForKey("level") )
                iLevel = (*it)->objectForKey("level")->toInt();


        }
    }

Check out http://www.arrowmania.com - Arrow Mania 2! For iOS, Android and Amazon Kindle Fire. Developed using Cocsos2D-X ;)

3DModelerMan
  • Posts: 23

#3 RE: 2012-07-28 01:10

Thanks. I’ll try and see if I can get it working. I was trying valueForKey but it always returns an empty string. Is that an unsupported function?

GMTDev
  • Posts: 205
  • Location: Vancouver, Canada

#4 RE: 2012-07-28 01:18

I couldn’t say, I wrote that months ago, based on the Test sample project I think. It works though, that’s my code I use from my game Arrow Mania (http://www.arrowmania.com).

Note the values “i0”, “i1”, “level”, etc are values added to the object by me in the editor (Tiled http://www.mapeditor.org), the others “x”,“y”,“width”,“height” are the standard values for each object.

Check out http://www.arrowmania.com - Arrow Mania 2! For iOS, Android and Amazon Kindle Fire. Developed using Cocsos2D-X ;)

3DModelerMan
  • Posts: 23

#5 RE: 2012-07-28 01:25

Nope. I’m still getting null strings. I tried using CCString* type = (CCString**)params->objectForKey; params is a CCDictionary** the weird thing is that when I try to use CCMutableArray instead I get errors. It says there’s no such class. I’m using the latest version of Cocos2D-x…

GMTDev
  • Posts: 205
  • Location: Vancouver, Canada

#6 RE: 2012-07-28 01:45

Try with this map file and my code, it should get the data from the object “089_jet_plane_1.png”

Files:
http://www.gmtdev.com/downloads/a\_map.tmx
http://www.gmtdev.com/downloads/map.png

I’m using “cocos2d-1.0.1-x-0.11.0”. One thing I noticed about the later versions was that the TMX tile map code would cause errors when releasing maps (though they did load). Hence I stayed at the old version. I’ve not gone to v2 as I want to support iPhone 3G.

a_map.tmx - tmx (1 kB)

Check out http://www.arrowmania.com - Arrow Mania 2! For iOS, Android and Amazon Kindle Fire. Developed using Cocsos2D-X ;)

3DModelerMan
  • Posts: 23

#7 RE: 2012-07-28 14:11

Thanks. I’ll try that when I get to the computer that has my code on it.

3DModelerMan
  • Posts: 23

#8 RE: 2012-07-28 23:03

I tried. The CCMutableArray doesn’t seem to exist anymore. The map and tileset don’t make any difference either. Is there anyone who has used the latest version to do this?

3DModelerMan
  • Posts: 23

#9 RE: 2012-07-28 23:48

I’ve even tried copying the code from the ortho object test and it won’t work. I attached my TMX file, maybe there actually IS something wrong with it?

level_1_1.tmx (1.6 kB)

3DModelerMan
  • Posts: 23

#10 RE: 2012-07-30 01:13

I ended up just writing my own object loader with TinyXML and it works great now.

dodohua
  • Posts: 2

#11 RE: 2012-07-31 16:19

i have the same question too. the TinyXML can not get the child count .not work to me. anyone have better idea?

3DModelerMan
  • Posts: 23

#12 RE: 2012-07-31 18:32

I just manually counted children. If anyone’s interested here’s my TinyXML code:
@
std::string fullPath = CCFileUtils::sharedFileUtils()~~>fullPathFromRelativePath);
unsigned char* pBuffer = NULL;
unsigned long bufferSize = 0;
pBuffer = CCFileUtils::sharedFileUtils~~>getFileData, “r”, &bufferSize);
if
{
//Load data
///////////////////////////////////////////////////////////////////////////////////////////////////
tinyxml2::XMLDocument doc;
doc.ParsepBuffer);
tinyxml2::XMLElement* map = doc.FirstChildElement;
if
{
tinyxml2::XMLElement* objects = map~~>FirstChildElement;
if
{
tinyxml2::XMLElement* firstChild = objects~~>FirstChildElement();
if ( firstChild )
{
tinyxml2::XMLElement* nextChild = firstChild;
while ( nextChild != NULL )
{
std::string elementName = nextChild~~>Name;
if )
{
onEntityElement;
}
nextChild = nextChild~~>NextSiblingElement();
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
}
@

@
void MapLoader::onEntityElement(tinyxml2::XMLElement* object, cocos2d::CCLayer* scene)
{
//Position and type
float x = object~~>FloatAttribute;
float y = object~~>FloatAttribute(“y”);

float width = object~~>FloatAttribute;
float height = object~~>FloatAttribute(“height”);

//x = (x)~~m_map~~>getMapSize().width*32;
y = (~~y)+m_map~~>getMapSize().height*32;

CCPoint pos = ccp(x,y);

std::string type = object~~>Attribute;
//Attributes
std::vector<SObjectParam> params;
tinyxml2::XMLElement* props = object~~>FirstChildElement(“properties”);
if ( props )
{
tinyxml2::XMLElement* firstChild = props~~>FirstChildElement;
if
{
tinyxml2::XMLElement* nextChild = firstChild;
while
{
if ) == std::string )
{
SObjectParam param;
param.m_name = nextChild~~>Attribute(“name”);
param.m_value = nextChild~~>Attribute;
params.push_back;
}
nextChild = nextChild~~>NextSiblingElement();
}
}
}

//Create entity
GameObject* obj = GameObjectFactory::createObject(type, pos, params, width, height);
if ( obj )
{
m_map->addChild(obj);
}
}@

EDIT: Woops. That wasn’t the TinyXML code where I counted the children. But in my other code I just had a counter in the while(nextChild!=NULL) loops.

GMTDev
  • Posts: 205
  • Location: Vancouver, Canada

#13 RE: 2012-08-11 00:56

I’ve just been updating to V2 and the code as in my v1 sample above is now as below. It’s just a slightly modified version of the code found in the taken from the Tests sample.

    CCTMXTiledMap* map = (CCTMXTiledMap*) getChildByTag(kTagTileMap);
    CCTMXObjectGroup* group = map->objectGroupNamed("Object Layer 1");
    CCArray* objects = group->getObjects();

    CCDictionary* dict = NULL;
    CCObject* pObj = NULL;

    CCARRAY_FOREACH(objects, pObj)
    {
        dict = (CCDictionary*)pObj;

        if(!dict)
            break;

        const char* key = "x";
        x = ((CCString*)dict->objectForKey(key))->intValue();
        key = "y";
        y = ((CCString*)dict->objectForKey(key))->intValue();
        key = "width";
        x2 = x+((CCString*)dict->objectForKey(key))->intValue();
        key = "height";
        y2 = y+((CCString*)dict->objectForKey(key))->intValue();         

        printf( "x %i, y %i, x2 %i, y2 %i\n", x, y, x2, y2 );
    }

Check out http://www.arrowmania.com - Arrow Mania 2! For iOS, Android and Amazon Kindle Fire. Developed using Cocsos2D-X ;)

umni4ek
  • Posts: 54

#14 RE: 2012-08-20 15:32

How did you run project with tinyxml on android? Is it work ?

3DModelerMan
  • Posts: 23

#15 RE: 2012-08-21 00:29

I’ve been developing on windows.

Loggin to reply

Copyright © 2010 - 2013 Cocos2d-x.orgClustrmaps