I've been poking through this. First, before I launch into a gripe fest that may come off as mean (but is not intended to be) let me say that this is a GREAT class (after making a few modifications). nice and lightweight. Works really well and makes it a pretty simple matter to plug whatever data I want into a TMX format and have Cocos2D load it up the same way it would any other map.
I definitely wish that CCTMXTiledMaps accepted XML strings in addition to TMX file names. I may need to make certain "modifications" to that class (shouldn't be that hard). Since I'm mainly interested in using this class for procedural generation and not user content generation, I don't really see the need for saving the result in user documents. I would rather have something to just generate an XML String and give me that. ;-)
ANYWAY, I have to grip a bit about the confusion here with regard to the "tileset properties."
First let me wal you through my unfolding perspective on the matter:
You made "propertiesForTileSetNamed" an OPTIONAL delegate method, but if that method isn't defined generateTMX returns an error. At first I thought that you forgot to add scope there so that the "if properties nil" check only occurs if the delegate responds to the selector. However it seems that the real issue is that this method should NOT be optional, because if it is omitted the map won't generate any layer GIDs other than 0. But on further inspection, the tileset properties code seems like it SHOULD be optional because it makes the entire process of determining GID a lot more complicated than it needs to be.
So I'm wondering to myself: why isn't there any way for this class to simply reference tiles in tilesets by their GIDs? I mean, as per your example, I'm creating a data array of GID values, which are all numbers. Why not just, I don't know, store that GID number directly, using the starting GID for the tileset, like how Tiled does it? Why does that number have to be squeezed through the grinder of a property dictionary? I mean, the tile property is part of Tiled, but it's an option, and it doesn't really work as you've using it here. This class makes it a requirement? The creation of a whole Dictionary with a key/value pair for every tile seems completely unnecessary. Is there something I'm missing here or maybe not understanding correctly?
Anyway, here's my simple gripe fixes:
NSString* tempStr = [self tileIDFromTileSet:tileSetForLayer thatMatchesKey:tileKeyVal property:tilePropertyVal];
if (tempStr)
GID += [tempStr intValue];
else
GID = [tilePropertyVal intValue];
On the last line, I've replaced "0" with the intValue of the string that was returned by tilePropertyForLayer. If it was a string, then that value will be 0, so no difference. If, like me (and your example) you're returning a tileset index, then that works a-ok. However, the better solution would be to have a "tileGIDForLayer" method that returns the gid, and then maybe a SEPARATE "tilePropertyForGID" method which looks up any properties you want associated with a particular GID? That really only needs to be done once for the whole map though, not once per tile. I still don't understand what you're trying to accomplish with "properties" vs GIDs. I figure it must be some project-specific need that's not really in line with the TMX paradigm.
and also:
if ([delegate_ respondsToSelector:@selector(propertiesForTileSetNamed:)])
{
properties = [delegate_ propertiesForTileSetNamed:key];
if (!properties)
{
if (error)
*error = [[NSError alloc] initWithDomain:[NSString stringWithFormat:@"Unable to get properties from tileset name %@ when calling delegate method propertiesForTileSetNamed:", key] code:0 userInfo:nil];
return NO;
}
}
Added brackets around the !properties check. Since the "propertiesForTileSetNamed" method is going to be optional, the !properties check would always pass and generate an error if the method wasn't defined. Which means, well, its not really optional heh. I happen to think that the dictionary generated by this method is completely superfluous, so I lean toward keeping the method optional of course.
My only remaining issue is that the asset copying code doesn't support tileset images in subdirectories. I keep my graphics in a subdirectories so they don't mix in with my maps. But, the way the file copying is set up it fails if the file being copied is in a subdirectory, because the subdirectory is in the file name and thats a nono. A fairly simple fix, but I'm not familiar enough with NSFileManager to work it out right now.
Still, this thing is a pretty solid foundation and I like it. I just want to see it grow into something better ;-)