From 5f12f2dd4aa1865f6d4db921a5e839e9c4943379 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Mon, 27 Jun 2011 23:26:48 -0700 Subject: [PATCH 01/13] First Submission of HKTMXTIledMap with Test --- Extensions/HKTMXTiledMap/HKTMXLayer.h | 97 ++++ Extensions/HKTMXTiledMap/HKTMXLayer.m | 425 ++++++++++++++++++ Extensions/HKTMXTiledMap/HKTMXTiledMap.h | 141 ++++++ Extensions/HKTMXTiledMap/HKTMXTiledMap.m | 200 +++++++++ Extensions/HKTMXTiledMap/README.md | 21 + .../HKTMXTiledMapTestLayer.h | 38 ++ .../HKTMXTiledMapTestLayer.m | 147 ++++++ Tests/HKTMXTiledMapTest/Resources/testmap.tmx | 23 + Tests/HKTMXTiledMapTest/Resources/tiles.png | Bin 0 -> 1838 bytes 9 files changed, 1092 insertions(+) create mode 100644 Extensions/HKTMXTiledMap/HKTMXLayer.h create mode 100644 Extensions/HKTMXTiledMap/HKTMXLayer.m create mode 100644 Extensions/HKTMXTiledMap/HKTMXTiledMap.h create mode 100644 Extensions/HKTMXTiledMap/HKTMXTiledMap.m create mode 100644 Extensions/HKTMXTiledMap/README.md create mode 100644 Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.h create mode 100755 Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m create mode 100644 Tests/HKTMXTiledMapTest/Resources/testmap.tmx create mode 100644 Tests/HKTMXTiledMapTest/Resources/tiles.png diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h new file mode 100644 index 0000000..1c3a040 --- /dev/null +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -0,0 +1,97 @@ + +#import "CCNode.h" + +@class CCTMXMapInfo; +@class CCTMXLayerInfo; +@class CCTMXTilesetInfo; + +/** + Represents a tile animation state. When animClock == 0.0, each tile is in a state + equal to its GID. After entering a state, a tile will look up the AnimRule for that + state, wait `delay` seconds, and then switch to state `next`. If `next` is zero, it + will stay in the state forever. + + As an optimization, `cycleTime` and `last` provide information about the complete + animation starting at this state. If `last` is zero, it is an endless loop + with a period of `cycleTime` seconds. If `last` is nonzero, it will reach state + `last` and terminate in a total of `cycleTime` seconds. + */ +struct HKTMXAnimRule { + double delay; + double cycleTime; + unsigned int next; + unsigned int last; +}; + +struct HKTMXAnimCacheEntry { + unsigned int state; + double validUntil; +}; + +@interface HKTMXLayer : CCNode +{ + CCTMXTilesetInfo *tileset_; + CCTexture2D *texture_; + NSString *layerName_; + CGSize layerSize_; + CGSize mapTileSize_; + CGSize screenGridSize_; + unsigned int *tiles_; + NSMutableArray *properties_; + unsigned char opacity_; + unsigned int minGID_; + unsigned int maxGID_; + GLuint buffers_[3]; + + double dirtyAt_; + CGPoint lastBaseTile_; + int lastVertexCount_; + + struct HKTMXAnimRule *animRules_; + struct HKTMXAnimCacheEntry *animCache_; + double animClock_; +} +/** name of the layer */ +@property (nonatomic,readwrite,retain) NSString *layerName; +/** size of the layer in tiles */ +@property (nonatomic,readwrite) CGSize layerSize; +/** size of the map's tile (could be differnt from the tile's size) */ +@property (nonatomic,readwrite) CGSize mapTileSize; +/** pointer to the map of tiles */ +@property (nonatomic,readwrite) unsigned int *tiles; +/** Tileset information for the layer */ +@property (nonatomic,readwrite,retain) CCTMXTilesetInfo *tileset; +/** Layer orientation, which is the same as the map orientation */ +@property (nonatomic,readwrite) int layerOrientation; +/** properties from the layer. They can be added using Tiled */ +@property (nonatomic,readwrite,retain) NSMutableArray *properties; + +/** creates an HKTMXLayer with a tileset info, a layer info and a map info */ ++(id) layerWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo; +/** initializes an HKTMXLayer with a tileset info, a layer info and a map info */ +-(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo; + +/** returns the tile gid at a given tile coordinate. + if it returns 0, it means that the tile is empty. + */ +-(unsigned int) tileGIDAt:(CGPoint)tileCoordinate; + +/** sets the tile gid (gid = tile global id) at a given tile coordinate. + The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1. + If a tile is already placed at that position, then it will be replaced. + */ +-(void) setTileGID:(unsigned int)gid at:(CGPoint)tileCoordinate; + +/** removes a tile at given tile coordinate */ +-(void) removeTileAt:(CGPoint)tileCoordinate; + +/** returns the position in pixels of a given tile coordinate */ +-(CGPoint) positionAt:(CGPoint)tileCoordinate; + +/** return the value for the specific property name */ +-(id) propertyNamed:(NSString *)propertyName; + +/** Creates the tiles */ +-(void) setupTiles; + +@end diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m new file mode 100644 index 0000000..8e0ed65 --- /dev/null +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -0,0 +1,425 @@ + +#import "HKTMXLayer.h" +#import "CCTMXTiledMap.h" +#import "CCTMXXMLParser.h" +#import "CCTextureCache.h" +#import "CCDirector.h" +#import "CGPointExtension.h" + +#pragma mark - +#pragma mark HKTMXLayer + +@interface HKTMXLayer (Private) +-(CGPoint) positionForOrthoAt:(CGPoint)pos; + +-(CGPoint) calculateLayerOffset:(CGPoint)offset; + +/* The layer recognizes some special properties, like cc_vertez */ +-(void) parseInternalProperties; + +@end + +@implementation HKTMXLayer +@synthesize layerSize = layerSize_, layerName = layerName_, tiles=tiles_; +@synthesize tileset=tileset_; +@synthesize layerOrientation=layerOrientation_; +@synthesize mapTileSize=mapTileSize_; +@synthesize properties=properties_; + +#pragma mark CCTMXLayer - init & alloc & dealloc + ++(id) layerWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo +{ + return [[[self alloc] initWithTilesetInfo:tilesetInfo layerInfo:layerInfo mapInfo:mapInfo] autorelease]; +} + +-(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo +{ + if((self=[super init])) + { + texture_ = [[CCTextureCache sharedTextureCache] addImage:tilesetInfo.sourceImage]; + tilesetInfo.imageSize = texture_.contentSize; + + // layerInfo + layerName_ = [layerInfo.name copy]; + layerSize_ = layerInfo.layerSize; + tiles_ = layerInfo.tiles; + minGID_ = tilesetInfo.firstGid; + maxGID_ = minGID_ + + (tilesetInfo.imageSize.width - tilesetInfo.margin * 2 + tilesetInfo.spacing) + / (tilesetInfo.tileSize.width + tilesetInfo.spacing) + * (tilesetInfo.imageSize.height - tilesetInfo.margin * 2 + tilesetInfo.spacing) + / (tilesetInfo.tileSize.height + tilesetInfo.spacing) + - 1; + opacity_ = layerInfo.opacity; + properties_ = [layerInfo.properties mutableCopy]; + + // tilesetInfo + tileset_ = [tilesetInfo retain]; + + // mapInfo + mapTileSize_ = mapInfo.tileSize; + layerOrientation_ = mapInfo.orientation; + + // offset (after layer orientation is set); + CGPoint offset = [self calculateLayerOffset:layerInfo.offset]; + [self setPosition:offset]; + + [self setContentSize: CGSizeMake( layerSize_.width * mapTileSize_.width, layerSize_.height * mapTileSize_.height )]; + + // adjust and validate tile IDs + NSAssert1(minGID_ <= maxGID_ + 1 && maxGID_ - minGID_ < 1000000, + @"TMX: Bad minGID/maxGID for layer %@", layerName_); + int tileCount = layerSize_.height * layerSize_.width; + for(int i=0; i < tileCount; i++) + { +#ifdef __BIG_ENDIAN__ + tiles_[i] = CFSwapInt32(tiles_[i]); +#endif + NSAssert(tiles_[i] == 0 || (tiles_[i] >= minGID_ && tiles_[i] <= maxGID_), + @"TMX: Only one tileset per layer is supported"); + } + + CGSize screenSize = [CCDirector sharedDirector].winSize; + screenGridSize_.width = ceil(screenSize.width / mapTileSize_.width) + 1; + screenGridSize_.height = ceil(screenSize.height / mapTileSize_.height) + 1; + int screenTileCount = screenGridSize_.width * screenGridSize_.height; + // create buffer objects + glGenBuffers(3, buffers_); + // generate a static vertex array covering the screen + glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); + glBufferData(GL_ARRAY_BUFFER, screenTileCount * 4 * 2 * sizeof(GLfloat), NULL, GL_STATIC_DRAW); +#if __IPHONE_OS_VERSION_MAX_ALLOWED + GLfloat *screenGrid = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); +#elif __MAC_OS_X_VERSION_MAX_ALLOWED + GLfloat *screenGrid = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); +#endif + GLfloat *tilePtr = screenGrid; + for (int y=0; y < screenGridSize_.height; y++) + { + GLfloat ypos_0 = mapTileSize_.height * y; + GLfloat ypos_1 = mapTileSize_.height * (y+1); + for (int x=0; x < screenGridSize_.width; x++, tilePtr += 4 * 2) + { + GLfloat xpos_0 = mapTileSize_.width * x; + GLfloat xpos_1 = mapTileSize_.width * (x+1); + // define the points of a quad here; we'll use the index buffer to make them triangles + tilePtr[0] = xpos_0; + tilePtr[1] = ypos_0; + tilePtr[2] = xpos_1; + tilePtr[3] = ypos_0; + tilePtr[4] = xpos_0; + tilePtr[5] = ypos_1; + tilePtr[6] = xpos_1; + tilePtr[7] = ypos_1; + } + } +#if __IPHONE_OS_VERSION_MAX_ALLOWED + glUnmapBufferOES(GL_ARRAY_BUFFER); +#elif __MAC_OS_X_VERSION_MAX_ALLOWED + glUnmapBuffer(GL_ARRAY_BUFFER); +#endif + // allocate texcoord buffer + glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); + glBufferData(GL_ARRAY_BUFFER, screenTileCount * 4 * 2 * sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW); + // allocate index buffer + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers_[2]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, screenTileCount * 6 * sizeof(GLushort), NULL, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // --= set up animations =-- + // XXX should belong to tileset or map to avoid redundancy + __block int animCount = 0; + // read relevant tile properties from the map + animRules_ = calloc(maxGID_ - minGID_ + 1, sizeof *animRules_); + animCache_ = calloc(maxGID_ - minGID_ + 1, sizeof *animCache_); + [mapInfo.tileProperties enumerateKeysAndObjectsUsingBlock: + ^(id key, id obj, BOOL *stop) + { + unsigned int idx = [key unsignedIntValue] - minGID_; + if (idx > maxGID_) return; + unsigned int next = [[obj objectForKey:@"Next"] intValue]; + double delay = [[obj objectForKey:@"Delay"] doubleValue]; + if (next && delay > 0) { + animRules_[idx].delay = delay; + animRules_[idx].next = next; + animCount++; + } + }]; + // find animation cycles and annotate + for (int gid=minGID_; gid <= maxGID_; gid++) + { + struct HKTMXAnimRule *rule = animRules_ + (gid - minGID_); + if (!rule->next) + { + // no animation here + rule->last = gid; + } + else if (!rule->cycleTime && !rule->last) + { + animCount++; + rule->cycleTime = rule->delay; + unsigned int state = rule->next; + while (1) + { + // found loop + if (state == gid) break; + // found endpoint + if (!animRules_[state - minGID_].next) + { + rule->last = state; + break; + } + // keep looking + rule->cycleTime += animRules_[state - minGID_].delay; + state = animRules_[state - minGID_].next; + } + // XXX propagate result forward through the cycle to avoid quadratic startup lag + } + } + animClock_ = 0.0; + dirtyAt_ = -INFINITY; + if (animCount > 0) + [self scheduleUpdate]; + } + return self; +} + +- (void) dealloc +{ + glDeleteBuffers(3, buffers_); + [layerName_ release]; + [tileset_ release]; + [properties_ release]; + + free(tiles_); + free(animRules_); + free(animCache_); + + [super dealloc]; +} + +- (void) update: (ccTime) delta +{ + animClock_ += delta; +} + +#pragma mark CCTMXLayer - setup Tiles + +-(void) setupTiles +{ + // Parse cocos2d properties + [self parseInternalProperties]; + +} + +#pragma mark CCTMXLayer - Properties + +-(id) propertyNamed:(NSString *)propertyName +{ + return [properties_ valueForKey:propertyName]; +} + +-(void) parseInternalProperties +{ + +} + +#pragma mark CCTMXLayer - obtaining tiles/gids + +-(unsigned int) tileGIDAt:(CGPoint)pos +{ + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); + + int idx = pos.x + (int)pos.y * (int)layerSize_.width; + return tiles_[idx]; +} + +#pragma mark CCTMXLayer - adding / remove tiles + +-(void) setTileGID:(unsigned int)gid at:(CGPoint)pos +{ + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); + NSAssert1(gid == 0 || (gid >= minGID_ && gid <= maxGID_), @"invalid gid (%u) for tileset", gid); + int idx = (int)pos.y * (int)layerSize_.width + pos.x; + tiles_[idx] = gid; + dirtyAt_ = -INFINITY; +} + +-(void) addChild: (CCNode*)node z:(int)z tag:(int)tag +{ + NSAssert(NO, @"addChild: is not supported on CCTMXLayer. Instead use setTileGID:at:/tileGIDAt:"); +} + +-(void) removeTileAt:(CGPoint)pos +{ + [self setTileGID:0 at:pos]; +} + +#pragma mark CCTMXLayer - obtaining positions, offset + +-(CGPoint) calculateLayerOffset:(CGPoint)pos +{ + CGPoint ret = CGPointZero; + switch( layerOrientation_ ) { + case CCTMXOrientationOrtho: + ret = ccp( pos.x * mapTileSize_.width, -pos.y *mapTileSize_.height); + break; + case CCTMXOrientationIso: + ret = ccp( (mapTileSize_.width /2) * (pos.x - pos.y), + (mapTileSize_.height /2 ) * (-pos.x - pos.y) ); + break; + case CCTMXOrientationHex: + NSAssert(CGPointEqualToPoint(pos, CGPointZero), @"offset for hexagonal map not implemented yet"); + break; + } + return ret; +} + +-(CGPoint) positionAt:(CGPoint)pos +{ + CGPoint ret = CGPointZero; + switch( layerOrientation_ ) { + case CCTMXOrientationOrtho: + ret = [self positionForOrthoAt:pos]; + break; + } + return ret; +} + +-(CGPoint) positionForOrthoAt:(CGPoint)pos +{ + int x = pos.x * mapTileSize_.width + 0.49f; + int y = (layerSize_.height - pos.y - 1) * mapTileSize_.height + 0.49f; + return ccp(x,y); +} + +#pragma mark CCTMXLayer - draw + +-(void) draw +{ + glBindTexture(GL_TEXTURE_2D, texture_.name); + // TODO: Do we EVER want a tiled map to be anti-aliased? + ccTexParams texParams = { GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE }; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParams.minFilter ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParams.magFilter ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParams.wrapS ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParams.wrapT ); + + glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); + glVertexPointer(2, GL_FLOAT, 0, NULL); + glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers_[2]); + CGAffineTransform trans = [self worldToNodeTransform]; + CGPoint baseTile = CGPointMake(floor(trans.tx / mapTileSize_.width), + floor(trans.ty / mapTileSize_.height)); + unsigned int vertexCount = 0; + if (dirtyAt_ > animClock_ && baseTile.x == lastBaseTile_.x && baseTile.y == lastBaseTile_.y) + { + vertexCount = lastVertexCount_; + goto texdone; + } + dirtyAt_ = INFINITY; + struct HKTMXAnimRule *AR = animRules_ - minGID_; + struct HKTMXAnimCacheEntry *AC = animCache_ - minGID_; +#if __IPHONE_OS_VERSION_MAX_ALLOWED + GLfloat *texcoords = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); + GLushort *indices = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES); +#elif __MAC_OS_X_VERSION_MAX_ALLOWED + GLfloat *texcoords = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + GLushort *indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); +#endif + CGSize texSize = tileset_.imageSize; + for (int y=0; y < screenGridSize_.height; y++) + { + if (baseTile.y + y < 0 || baseTile.y + y >= layerSize_.height) + continue; + for (int x=0; x < screenGridSize_.width; x++) + { + if (baseTile.x + x < 0 || baseTile.x + x >= layerSize_.width) + continue; + int tileidx = (layerSize_.height - (baseTile.y + y) - 1) * layerSize_.width + + baseTile.x + x; + unsigned int tile = tiles_[tileidx]; + if (!tile) continue; + unsigned int showtile; + if (AC[tile].validUntil <= animClock_) + { + if (AR[tile].last && animClock_ >= AR[tile].cycleTime) + { + showtile = AR[tile].last; + AC[tile].state = showtile; + AC[tile].validUntil = INFINITY; + } + else + { + double phase = AR[tile].last ? animClock_ : fmod(animClock_, AR[tile].cycleTime); + showtile = tile; + while (phase > AR[showtile].delay) + { + phase -= AR[showtile].delay; + showtile = AR[showtile].next; + } + AC[tile].state = showtile; + AC[tile].validUntil = animClock_ + AR[showtile].delay - phase; + } + } + else + showtile = AC[tile].state; + dirtyAt_ = MIN(dirtyAt_, AC[tile].validUntil); + int screenidx = y * screenGridSize_.width + x; + CGRect tileTexture = [tileset_ rectForGID:showtile]; + tileTexture.origin.x /= texSize.width; + tileTexture.origin.y /= texSize.height; + tileTexture.size.width /= texSize.width; + tileTexture.size.height /= texSize.height; + GLfloat *texbase = texcoords + screenidx * 4 * 2; + GLushort *idxbase = indices + vertexCount; + int vertexbase = screenidx * 4; + + texbase[0] = tileTexture.origin.x; + texbase[1] = tileTexture.origin.y + tileTexture.size.height; + texbase[2] = tileTexture.origin.x + tileTexture.size.width; + texbase[3] = tileTexture.origin.y + tileTexture.size.height; + texbase[4] = tileTexture.origin.x; + texbase[5] = tileTexture.origin.y; + texbase[6] = tileTexture.origin.x + tileTexture.size.width; + texbase[7] = tileTexture.origin.y; + + idxbase[0] = vertexbase; + idxbase[1] = vertexbase + 1; + idxbase[2] = vertexbase + 2; + idxbase[3] = vertexbase + 3; + idxbase[4] = vertexbase + 2; + idxbase[5] = vertexbase + 1; + vertexCount += 6; + } + } +#if __IPHONE_OS_VERSION_MAX_ALLOWED + glUnmapBufferOES(GL_ARRAY_BUFFER); + glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER); +#elif __MAC_OS_X_VERSION_MAX_ALLOWED + glUnmapBuffer(GL_ARRAY_BUFFER); + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); +#endif + lastBaseTile_ = baseTile; + lastVertexCount_ = vertexCount; + +texdone: + glPushMatrix(); + glTranslatef(baseTile.x * mapTileSize_.width, baseTile.y * mapTileSize_.height, 0); + glDisableClientState(GL_COLOR_ARRAY); + glColor4f(1, 1, 1, 1); + glTexCoordPointer(2, GL_FLOAT, 0, NULL); + glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, NULL); + glEnableClientState(GL_COLOR_ARRAY); + glPopMatrix(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +@end + diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.h b/Extensions/HKTMXTiledMap/HKTMXTiledMap.h new file mode 100644 index 0000000..9f3872b --- /dev/null +++ b/Extensions/HKTMXTiledMap/HKTMXTiledMap.h @@ -0,0 +1,141 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009-2010 Ricardo Quesada + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * TMX Tiled Map support: + * http://www.mapeditor.org + * + */ +#include "HKTMXLayer.h" + +@class CCTMXObjectGroup; + +///** Possible oritentations of the TMX map */ +//enum +//{ +// /** Orthogonal orientation */ +// CCTMXOrientationOrtho, +// +// /** Hexagonal orientation */ +// CCTMXOrientationHex, +// +// /** Isometric orientation */ +// CCTMXOrientationIso, +//}; + +/** CCTMXTiledMap knows how to parse and render a TMX map. + + It adds support for the TMX tiled map format used by http://www.mapeditor.org + It supports isometric, hexagonal and orthogonal tiles. + It also supports object groups, objects, and properties. + + Features: + - Each tile will be treated as an CCSprite + - The sprites are created on demand. They will be created only when you call "[layer tileAt:]" + - Each tile can be rotated / moved / scaled / tinted / "opacitied", since each tile is a CCSprite + - Tiles can be added/removed in runtime + - The z-order of the tiles can be modified in runtime + - Each tile has an anchorPoint of (0,0) + - The anchorPoint of the TMXTileMap is (0,0) + - The TMX layers will be added as a child + - The TMX layers will be aliased by default + - The tileset image will be loaded using the CCTextureCache + - Each tile will have a unique tag + - Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z + - Each object group will be treated as an NSMutableArray + - Object class which will contain all the properties in a dictionary + - Properties can be assigned to the Map, Layer, Object Group, and Object + + Limitations: + - It only supports one tileset per layer. + - Embeded images are not supported + - It only supports the XML format (the JSON format is not supported) + + Technical description: + Each layer is created using an CCTMXLayer (subclass of CCSpriteSheet). If you have 5 layers, then 5 CCTMXLayer will be created, + unless the layer visibility is off. In that case, the layer won't be created at all. + You can obtain the layers (CCTMXLayer objects) at runtime by: + - [map getChildByTag: tag_number]; // 0=1st layer, 1=2nd layer, 2=3rd layer, etc... + - [map layerNamed: name_of_the_layer]; + + Each object group is created using a CCTMXObjectGroup which is a subclass of NSMutableArray. + You can obtain the object groups at runtime by: + - [map objectGroupNamed: name_of_the_object_group]; + + Each object is a CCTMXObject. + + Each property is stored as a key-value pair in an NSMutableDictionary. + You can obtain the properties at runtime by: + + [map propertyNamed: name_of_the_property]; + [layer propertyNamed: name_of_the_property]; + [objectGroup propertyNamed: name_of_the_property]; + [object propertyNamed: name_of_the_property]; + + @since v0.8.1 + */ +@interface HKTMXTiledMap : CCNode +{ + CGSize mapSize_; + CGSize tileSize_; + int mapOrientation_; + NSMutableArray *objectGroups_; + NSMutableDictionary *properties_; + NSMutableDictionary *tileProperties_; +} + +/** the map's size property measured in tiles */ +@property (nonatomic,readonly) CGSize mapSize; +/** the tiles's size property measured in pixels */ +@property (nonatomic,readonly) CGSize tileSize; +/** map orientation */ +@property (nonatomic,readonly) int mapOrientation; +/** object groups */ +@property (nonatomic,readwrite,retain) NSMutableArray *objectGroups; +/** properties */ +@property (nonatomic,readwrite,retain) NSMutableDictionary *properties; + +/** creates a TMX Tiled Map with a TMX file.*/ ++(id) tiledMapWithTMXFile:(NSString*)tmxFile; + +/** initializes a TMX Tiled Map with a TMX file */ +-(id) initWithTMXFile:(NSString*)tmxFile; + +/** return the TMXLayer for the specific layer */ +-(HKTMXLayer*) layerNamed:(NSString *)layerName; + +/** return the TMXObjectGroup for the secific group */ +-(CCTMXObjectGroup*) objectGroupNamed:(NSString *)groupName; + +/** return the TMXObjectGroup for the secific group + @deprecated Use map#objectGroupNamed instead + */ +-(CCTMXObjectGroup*) groupNamed:(NSString *)groupName DEPRECATED_ATTRIBUTE; + +/** return the value for the specific property name */ +-(id) propertyNamed:(NSString *)propertyName; + +/** return properties dictionary for tile GID */ +-(NSDictionary*)propertiesForGID:(unsigned int)GID; +@end + diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m new file mode 100644 index 0000000..5c6cfe5 --- /dev/null +++ b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m @@ -0,0 +1,200 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009-2010 Ricardo Quesada + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * TMX Tiled Map support: + * http://www.mapeditor.org + * + */ + +#import "HKTMXTiledMap.h" +#import "CCTMXXMLParser.h" +#import "CCTMXObjectGroup.h" +#import "CCSprite.h" +#import "CCTextureCache.h" +#import "CGPointExtension.h" +#import "ccMacros.h" + +#pragma mark - +#pragma mark CCTMXTiledMap + +@interface HKTMXTiledMap (Private) +-(id) parseLayer:(CCTMXLayerInfo*)layer map:(CCTMXMapInfo*)mapInfo; +-(CCTMXTilesetInfo*) tilesetForLayer:(CCTMXLayerInfo*)layerInfo map:(CCTMXMapInfo*)mapInfo; +@end + +@implementation HKTMXTiledMap +@synthesize mapSize=mapSize_; +@synthesize tileSize=tileSize_; +@synthesize mapOrientation=mapOrientation_; +@synthesize objectGroups=objectGroups_; +@synthesize properties=properties_; + ++(id) tiledMapWithTMXFile:(NSString*)tmxFile +{ + return [[[self alloc] initWithTMXFile:tmxFile] autorelease]; +} + +-(id) initWithTMXFile:(NSString*)tmxFile +{ + NSAssert(tmxFile != nil, @"TMXTiledMap: tmx file should not bi nil"); + + if ((self=[super init])) { + + [self setContentSize:CGSizeZero]; + + CCTMXMapInfo *mapInfo = [CCTMXMapInfo formatWithTMXFile:tmxFile]; + + NSAssert( [mapInfo.tilesets count] != 0, @"TMXTiledMap: Map not found. Please check the filename."); + + mapSize_ = mapInfo.mapSize; + tileSize_ = mapInfo.tileSize; + mapOrientation_ = mapInfo.orientation; + objectGroups_ = [mapInfo.objectGroups retain]; + properties_ = [mapInfo.properties retain]; + tileProperties_ = [mapInfo.tileProperties retain]; + + int idx=0; + + for( CCTMXLayerInfo *layerInfo in mapInfo.layers ) { + + if( layerInfo.visible ) { + id child = [self parseLayer:layerInfo map:mapInfo]; + [self addChild:child z:idx tag:idx]; + + // update content size with the max size + CGSize childSize = [child contentSize]; + CGSize currentSize = [self contentSize]; + currentSize.width = MAX( currentSize.width, childSize.width ); + currentSize.height = MAX( currentSize.height, childSize.height ); + [self setContentSize:currentSize]; + + idx++; + } + } + } + + return self; +} + +-(void) dealloc +{ + [objectGroups_ release]; + [properties_ release]; + [tileProperties_ release]; + [super dealloc]; +} + +// private +-(id) parseLayer:(CCTMXLayerInfo*)layerInfo map:(CCTMXMapInfo*)mapInfo +{ + CCTMXTilesetInfo *tileset = [self tilesetForLayer:layerInfo map:mapInfo]; + HKTMXLayer *layer = [HKTMXLayer layerWithTilesetInfo:tileset layerInfo:layerInfo mapInfo:mapInfo]; + + // tell the layerinfo to release the ownership of the tiles map. + layerInfo.ownTiles = NO; + + [layer setupTiles]; + + return layer; +} + +-(CCTMXTilesetInfo*) tilesetForLayer:(CCTMXLayerInfo*)layerInfo map:(CCTMXMapInfo*)mapInfo +{ + CCTMXTilesetInfo *tileset = nil; + CFByteOrder o = CFByteOrderGetCurrent(); + + CGSize size = layerInfo.layerSize; + + id iter = [mapInfo.tilesets reverseObjectEnumerator]; + for( CCTMXTilesetInfo* tileset in iter) { + for( unsigned int y=0; y < size.height; y++ ) { + for( unsigned int x=0; x < size.width; x++ ) { + + unsigned int pos = x + size.width * y; + unsigned int gid = layerInfo.tiles[ pos ]; + + // gid are stored in little endian. + // if host is big endian, then swap + if( o == CFByteOrderBigEndian ) + gid = CFSwapInt32( gid ); + + // XXX: gid == 0 --> empty tile + if( gid != 0 ) { + + // Optimization: quick return + // if the layer is invalid (more than 1 tileset per layer) an assert will be thrown later + if( gid >= tileset.firstGid ) + return tileset; + } + } + } + } + + // If all the tiles are 0, return empty tileset + CCLOG(@"cocos2d: Warning: TMX Layer '%@' has no tiles", layerInfo.name); + return tileset; +} + + +// public + +-(HKTMXLayer*) layerNamed:(NSString *)layerName +{ + for( HKTMXLayer *layer in children_ ) { + if([layer isKindOfClass:[HKTMXLayer class]]){ + if( [layer.layerName isEqual:layerName] ) + return layer; + } + } + + // layer not found + return nil; +} + +-(CCTMXObjectGroup*) objectGroupNamed:(NSString *)groupName +{ + for( CCTMXObjectGroup *objectGroup in objectGroups_ ) { + if( [objectGroup.groupName isEqual:groupName] ) + return objectGroup; + } + + // objectGroup not found + return nil; +} + +// XXX deprecated +-(CCTMXObjectGroup*) groupNamed:(NSString *)groupName +{ + return [self objectGroupNamed:groupName]; +} + +-(id) propertyNamed:(NSString *)propertyName +{ + return [properties_ valueForKey:propertyName]; +} +-(NSDictionary*)propertiesForGID:(unsigned int)GID{ + return [tileProperties_ objectForKey:[NSNumber numberWithInt:GID]]; +} +@end + diff --git a/Extensions/HKTMXTiledMap/README.md b/Extensions/HKTMXTiledMap/README.md new file mode 100644 index 0000000..6717c0e --- /dev/null +++ b/Extensions/HKTMXTiledMap/README.md @@ -0,0 +1,21 @@ +HKTMXTiledMap +================== + +CCTMXTiledMap is useful, but it's absurdly slow for large maps, thus, HKTMXTiledMap is born. +It only supports orthogonal maps (no hex or isometric maps). + +Animation +------------------------ + + To animate tiles, you edit tile properties (via Tiled or whatever editor) to have "Next" which lists the next GID in the animation, and Delay (the delay between frames). It supports looped and one shot animations, but all animations have to be deterministic (no random) + +How to create +------------------------ + +Created just like a CCTMXTiledMap. + + +Known issues +------------------------ +* Doesn't currently work with retina display enabled +* Mac Version doesn't like window resizing \ No newline at end of file diff --git a/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.h b/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.h new file mode 100644 index 0000000..5b3bac9 --- /dev/null +++ b/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.h @@ -0,0 +1,38 @@ +/* + * CCBigImage Tests + * + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions + * + * Copyright (c) 2011 Stepan Generalov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// When you import this file, you import all the cocos2d classes +#import "cocos2d.h" + + +@interface HKTMXTiledMapTestLayer : CCLayer +{ + +} + +@end diff --git a/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m b/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m new file mode 100755 index 0000000..bd87f6d --- /dev/null +++ b/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m @@ -0,0 +1,147 @@ +/* + * CCBigImage Tests + * + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions + * + * Copyright (c) 2011 Stepan Generalov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +// Import the interfaces +#import "HKTMXTiledMap.h" +#import "HKTMXTiledMapTestLayer.h" +#import "ExtensionTest.h" + +SYNTHESIZE_EXTENSION_TEST(HKTMXTiledMapTestLayer) + +// HelloWorldLayer implementation +@implementation HKTMXTiledMapTestLayer + +// on "init" you need to initialize your instance +-(id) init +{ + // always call "super" init + // Apple recommends to re-assign "self" with the "super" return value + if( (self=[super init])) { + + // prepare scroll stuff +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + self.isTouchEnabled = YES; +#elif __MAC_OS_X_VERSION_MIN_REQUIRED + self.isMouseEnabled = YES; + [[CCDirector sharedDirector] setResizeMode:kCCDirectorResize_AutoScale]; +#endif + [[CCDirector sharedDirector] setProjection:kCCDirectorProjection2D]; + HKTMXTiledMap* node = [HKTMXTiledMap tiledMapWithTMXFile:@"testmap.tmx"]; + + // Add node as child + node.position = ccp(0,0); + [self addChild: node]; + } + return self; +} + +// on "dealloc" you need to release all your retained objects +- (void) dealloc +{ + // in case you have something to dealloc, do it in this method + // in this particular example nothing needs to be released. + // cocos2d will automatically release all the children (Label) + + // don't forget to call "super dealloc" + [super dealloc]; +} + +- (void) updateForScreenReshape +{ +} + + +#pragma mark Scrolling + +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +-(void) registerWithTouchDispatcher +{ + [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:kCCMenuTouchPriority swallowsTouches:YES]; +} + +-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event +{ + return YES; +} + +-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event +{ + CGRect boundaryRect = CGRectMake(0, 0, + [[CCDirector sharedDirector] winSize].width, + [[CCDirector sharedDirector] winSize].height ); + + // scrolling is allowed only with non-zero boundaryRect + if (!CGRectIsNull(boundaryRect)) + { + // get touch move delta + CGPoint point = [touch locationInView: [touch view]]; + CGPoint prevPoint = [ touch previousLocationInView: [touch view] ]; + point = [ [CCDirector sharedDirector] convertToGL: point ]; + prevPoint = [ [CCDirector sharedDirector] convertToGL: prevPoint ]; + CGPoint delta = ccpSub(point, prevPoint); + + CGPoint newPosition = ccpAdd(self.position, delta ); + self.position = newPosition; + + // stay in externalBorders + } +} + +#elif __MAC_OS_X_VERSION_MIN_REQUIRED +-(BOOL) ccMouseDragged:(NSEvent*)event +{ + CGPoint delta = ccp( [event deltaX], - [event deltaY] ); + + // fix scrolling speed if we are scaled + delta = ccp(delta.x / self.scaleX, delta.y / self.scaleY); + + // add delta + CGPoint newPosition = ccpAdd(self.position, delta ); + self.position = newPosition; + + return NO; +} + +- (BOOL)ccScrollWheel:(NSEvent *)theEvent +{ + CGPoint delta = ccp( [theEvent deltaX], - [theEvent deltaY] ); + + // add delta + CGPoint newPosition = ccpAdd(self.position, delta ); + self.position = newPosition; + + // stay in externalBorders + //[self fixPosition]; + + return NO; +} + +#endif + +@end diff --git a/Tests/HKTMXTiledMapTest/Resources/testmap.tmx b/Tests/HKTMXTiledMapTest/Resources/testmap.tmx new file mode 100644 index 0000000..1275d30 --- /dev/null +++ b/Tests/HKTMXTiledMapTest/Resources/testmap.tmx @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + H4sIAAAAAAAAA+2c3VIsMQiE1fP+73yurNoaJwkBAg3piy51dSfAlz9I3O+vr69viqJe9TNQtl3UX0bZdlBkgizywBJ5YIk8sEQeWCIPLJEHlsgDR8w/cEQWWCILHHFsYIkssEQeWCIPLJEHlsgDS+SBJfLAkobH6E4E2cbzWMWdXOJ4SGNNJmd5aOYj8vBlYl0XyMPGw3ttJg8skQeWyANL5IEl8sAR8w8ckUVMfCVxJosYFjM+rCfmsaDI4WaRA4Y4JrBEFjgiCxyRBZbIA0dkgSXywBFZ4Ii5BpbIA09kgifWyrFFHlgiDyyRB5bIA0vkgSXywBL3vPmx/1m8tvodGfrx+Pz6jO0sV3y+RibneWieRyY2FrPvrc/tprd5OpKHprbFMeLD4zl3ecxbldh42Gl5xmjsva0pFj6oTNBskoyPt99p+z2a/2jcV+vHaJw8n6FpjzrDQ8sfwWc0rdaJjjyQJd1HkUcsj08mo9rU6jnSvCTbT2SN7HyrU1l9rhKTbB4zJqufpTUv1PwDUbNcQrLOz2q+p/Pzzow16wZqXLLrHl7taesjq3kKjRcS9902VnPP7DXp+oIWC6T+I93bztYcSy5D7cXTytPCxJtllb6hmfdvritG+TPbu1r3tBofmN/POXX28SamnffAnvGZybsNT9u/B8+suJ7t5HxWecW+s1B9RLXrtO2s9eWx0uTT3YTiK2sYddhVHSMVbaZvdf2tYGMX7eQY2bZG+oxuB4oP1B4Tyblhth+7fiHaPLPNejZI2Zns1p/IRB/rys+n9nlUrY117UtV/apqd7ZfkedN1RllruvWtkfvrczkhn1WJf8qzhGzs3iNvRm8OuWF0rqEx99E+uRlT5X7IdntV7Ut2n6EWCDYcMKfinPwp83/XpRt3y169p03FuQSw+A5hlcspDyq1r4y4j/yScKCY8SHgeTvyUMfZ08ON/GInO92zwG1LJ48TtXvqq8VFvstPChfFrs8sn2tII+x7c2j+nxj8cXLd46NHH6/71ndi6uuk/54/Q+IdL/cNY4o9u/GOfsMPTumVvtP3QPNuGfyE9h+JBuPPn56nOzmkwjzabZQeHTdd1Tl8ckkOyYZDDz7oybu2THwjuFOPLPykK7jQJOfoMzHln6Eqt1+huTvjn1Idmv8fNqO6M8NPKqwmPGQ+uXd9glfdnxEVKd1vtM4rybpOKjOoor9ktjv5CDZ/qDF8hSPbF9vloRHl7xr5B+SVjxGe+Fsu7tKwmP1Hson9ho+5BHPbLRedFlDUKTJ/TzXci+OJ/oDUh+b1bC1dnIcYfQBMsAV2eTFh7GPj1lGXhjNOaM9aZvI+6FueuYVn6wYv96qPq91q1Eg2Y5ky5tdz683xQBBmvOOyDrJzeyk9d5Ta/ytsY/0GynGSLbQv/7+a+xB8wFJjA1FjYVyvoeibv7coM7MOvvGePTwi3vW2mKd8azN1c8iRm1F1Kk7xOsW2z1yCVTfbtXOOeTo8/jI1B770fcjST4f8RYu2X7y8yp9WHhx7MYju3978/D0uXpsUJQVR892Pfenp/43g3tgO0vvGL7dBzrNqFofWNl74o407/LuxdIyV2X7gSCPOMx4SPsyeZxhoL1zjchDMh9n27hrC8eHPTZWLtb1pBobhHvZbzmH996nGhf0PuGdfyCctXnaoF1rd+MdlatxHI59yfAJOS9EtUsT3521KOOOwg2azX2/34/OPN5yUMQ4otixsnFVl1zxeDLpdncosu2d+WjFI5pJN+2uD7Mz2p1xRvnUtVZn5l1i7l2L8mr32Z5lfFj8Ph0HL7tOtDuqw6yeEbmn6joveuUXlWoBp/tDxLOftSu0+HjHMXsvXTG2iLo1jl39/g+IztKtgDgBAA== + + + diff --git a/Tests/HKTMXTiledMapTest/Resources/tiles.png b/Tests/HKTMXTiledMapTest/Resources/tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..120de664a7d8de9e03ae84fd2e2e93c19dc0522c GIT binary patch literal 1838 zcmV+}2hsS6P)0008+X+uL$Nkc;* zP;zf(X>4Tx0C)j~RL^S@K@|QrZmG~B2wH0nvUrdpNm;9CMbtL^5n^i$+aIn^?(HA4aZWV5ov6ELTdbo0FI&wK{O>*+w4vx20?>!`FrQsdJlnHR>OPy zcd~b_n$otK2Za4V;76L-DzNVtaSB-y0*E}{p()372;bw_^6ZZ}PI-92wGS&j#91PI zKs7DSe@(bk%_Y-7gGe}(^>I=@oY#w#*Bu9GZf3^F5WP>3rn}7Ut74&?PWBFvy`A)a zPP5)V!Xd&78LdA?xQ(9mjMYElVd13a#D+Z_7&Y|xU=_C-srWU*6kiZcC!$nw*)9$7 zn6CX+@=AhmkT}X@VSsa5NKe;HZuq)~1$`#h6R+ZTR#D-3j}vF!)ZOnz+5)dI4jl{{ z44Mr{P!L4~VVJN`K!!XTF*LGrKO?IK8z<8w`3e3jI8lUGNUta*C8 zn(P`s>{pjD=7Kek#B;Fw@hxAK%$F&Q6vg9J^Xf~4by_hu-=A!MJ3Znq&n~srbFGPs zH&&aMXZ>nO`|hf|ljc?VPhR!${AbO?W8x_>CU%PFA&Hm8F7cAsOREdwU~R_;ot1_u z(ruCYB-LPGn!NQdT|ZlRy+(fw^-+`=%+gee_kY4FWHg<*4sZI8+sFJD270UUORdLHO0nA4V) z%{fwsET5CQ>B?eK%uw4yQc~9?*JVo2}ze(;aRcp*ceL#HUJSllrgm5wQKR zQu+C;QrUh^8rFfA`ftFz{YAidi-`aL010qNS#tmY3ljhU3ljkVnw%H_00ZVpL_t(& z1?^bDapN!yl+%TuZbfa})2+CTd%6v`lBe1@fDl$oO3En)1a8Tb9AL2UXoZoI)>7+b(BToYh&kH@4_7H*7XOGJ!flToYi@h?|Hv6mbYCcx53z3eF^mH>zWbf$fDU23zndfvo#}EshX^{47ue z9}{4W*-=?IcsJ_C@pm6+tT3CJ#!wpXXW>;1NOblLHjCiq88`=-WZ{|slis5MObDZn zOrTB>*94d};wIt^MI1s3URj8bf-?!?jp~?UV0&ST!4|wqVD0|S!i5mzXMrO4m;h_c zj>^KpyHPiezxzOAh1t|JhSGRH3$JQGqO)hPSp+xFz&Xey3)cjg^d1FZLKt;q0(FA8 zCcvZ-HxX|r;t*2s%0he;oJkOGRL2wp+Y3_+w%}C)S@-=~93cexS)d3$CcqlAqq1=D zZq$wAhwlTYt{;YbcRv4Z&a~^VS-3`iEW}U2KP0rW@2~o2j}5YLuop!J-@-PstYY}7 z>uyTD#F7ope@Lw?T1#30;Y%l6B7qbW9-d5^dlSA6k1tUT#R!X zhJgyeILT`_3{)7F!vdSKevZ@nO2|faQ$$_^xE8TQ7(?jDpF%4Emw1+sijr^9(g$3C zoFeO1inY7yQQKbjKX>1E!YkEiJ>z|adkwfq(IT4)LwzVuWySH`OpCtzfQanpyWCG? zfm>w{iyo~H%q;3PU_y=+Hr*QnZ@upqKU)rG@&1-`OTp_tV5PjU>;LcjiVekqe^d(h zlHWy>{q$Y?l#afE=k)=*8K+)uM4U~b{_FdIv0wjk7P;?L2|qxNgBmC%kwwKnyc!=< zP#%vm4Zg(JtX1Jwnse)t6|41xAEytjSoBc82bL`Qsy=}GJKLhDf%+E1e&TO4oEiOz zv3woc^C#<4A1H3CzJyWHRBSfjRjoG{fT<&|0X(k{NHURqFw`XDA*%+`~!WU zxb3_5{n~n59qL>6z&J3aV)(lcsIdOHz+7bdp5u}Gel3pI01BY^hgV~J1?6!z)8I>d c&01ObKc)#l$nr{}OaK4?07*qoM6N<$g1E(QqyPW_ literal 0 HcmV?d00001 From af568258e880153a57c88560c272395aa90d7404 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Wed, 29 Jun 2011 00:29:01 -0700 Subject: [PATCH 02/13] * Added Copyrights * Made Blocks Optional * elucidated ReadMe --- Extensions/HKTMXTiledMap/HKTMXLayer.h | 34 ++- Extensions/HKTMXTiledMap/HKTMXLayer.m | 56 ++++- Extensions/HKTMXTiledMap/HKTMXTiledMap.h | 16 +- Extensions/HKTMXTiledMap/HKTMXTiledMap.m | 15 +- Extensions/HKTMXTiledMap/README.md | 13 +- .../HKTMXTiledMapTestLayer.m | 2 + .../project.pbxproj | 218 ++++++++++++++++++ .../project.pbxproj | 178 ++++++++++++++ 8 files changed, 512 insertions(+), 20 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h index 1c3a040..a66d613 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.h +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -1,4 +1,36 @@ - +/* + * HKTMXTiledMap + * + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions + * + * HKASoftware + * http://hkasoftware.com + * + * Copyright (c) 2011 HKASoftware + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * TMX Tiled Map support: + * http://www.mapeditor.org + * + */ #import "CCNode.h" @class CCTMXMapInfo; diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 8e0ed65..889ec7b 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -1,3 +1,36 @@ +/* + * HKTMXTiledMap + * + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions + * + * HKASoftware + * http://hkasoftware.com + * + * Copyright (c) 2011 HKASoftware + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * TMX Tiled Map support: + * http://www.mapeditor.org + * + */ #import "HKTMXLayer.h" #import "CCTMXTiledMap.h" @@ -134,8 +167,9 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn __block int animCount = 0; // read relevant tile properties from the map animRules_ = calloc(maxGID_ - minGID_ + 1, sizeof *animRules_); - animCache_ = calloc(maxGID_ - minGID_ + 1, sizeof *animCache_); - [mapInfo.tileProperties enumerateKeysAndObjectsUsingBlock: + animCache_ = calloc(maxGID_ - minGID_ + 1, sizeof *animCache_); +#if NS_BLOCKS_AVAILABLE + [mapInfo.tileProperties enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) { unsigned int idx = [key unsignedIntValue] - minGID_; @@ -148,6 +182,22 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn animCount++; } }]; +#else + + for(id key in [mapInfo.tileProperties keyEnumerator]) + { + unsigned int idx = [key unsignedIntValue] - minGID_; + if (idx > maxGID_) continue; + id obj = [mapInfo.tileProperties objectForKey:key]; + unsigned int next = [[obj objectForKey:@"Next"] intValue]; + double delay = [[obj objectForKey:@"Delay"] doubleValue]; + if (next && delay > 0) { + animRules_[idx].delay = delay; + animRules_[idx].next = next; + animCount++; + } + } +#endif // find animation cycles and annotate for (int gid=minGID_; gid <= maxGID_; gid++) { @@ -248,7 +298,7 @@ -(void) setTileGID:(unsigned int)gid at:(CGPoint)pos dirtyAt_ = -INFINITY; } --(void) addChild: (CCNode*)node z:(int)z tag:(int)tag +-(void) addChild: (CCNode*)node z:(NSInteger)z tag:(NSInteger)tag { NSAssert(NO, @"addChild: is not supported on CCTMXLayer. Instead use setTileGID:at:/tileGIDAt:"); } diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.h b/Extensions/HKTMXTiledMap/HKTMXTiledMap.h index 9f3872b..b2bffba 100644 --- a/Extensions/HKTMXTiledMap/HKTMXTiledMap.h +++ b/Extensions/HKTMXTiledMap/HKTMXTiledMap.h @@ -1,18 +1,24 @@ /* - * cocos2d for iPhone: http://www.cocos2d-iphone.org + * HKTMXTiledMap * - * Copyright (c) 2009-2010 Ricardo Quesada + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions * + * HKASoftware + * http://hkasoftware.com + * + * Copyright (c) 2011 HKASoftware + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,8 +26,6 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * - * * TMX Tiled Map support: * http://www.mapeditor.org * diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m index 5c6cfe5..b00b7eb 100644 --- a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m +++ b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m @@ -1,18 +1,24 @@ /* - * cocos2d for iPhone: http://www.cocos2d-iphone.org + * HKTMXTiledMap * - * Copyright (c) 2009-2010 Ricardo Quesada + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions * + * HKASoftware + * http://hkasoftware.com + * + * Copyright (c) 2011 HKASoftware + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,7 +27,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * - * * TMX Tiled Map support: * http://www.mapeditor.org * diff --git a/Extensions/HKTMXTiledMap/README.md b/Extensions/HKTMXTiledMap/README.md index 6717c0e..016fe13 100644 --- a/Extensions/HKTMXTiledMap/README.md +++ b/Extensions/HKTMXTiledMap/README.md @@ -1,8 +1,9 @@ HKTMXTiledMap ================== -CCTMXTiledMap is useful, but it's absurdly slow for large maps, thus, HKTMXTiledMap is born. -It only supports orthogonal maps (no hex or isometric maps). +CCTMXTiledMap is useful, but it's absurdly slow for large maps, thus, HKTMXTiledMap is born. By pushing only polygons needed to the GPU, it drastically reduces render times by the GPU. +Currently, it only supports orthogonal maps (no hex or isometric maps). +Also added to it is animation functionality. This allows you to have data-driven animated tiles as done through the Tile Properties. Animation ------------------------ @@ -12,10 +13,12 @@ Animation How to create ------------------------ -Created just like a CCTMXTiledMap. +Maps should be made in Tiled http://www.mapeditor.org +Created just like a CCTMXTiledMap. + HKTMXTiledMap* node = [HKTMXTiledMap tiledMapWithTMXFile:@"testmap.tmx"]; Known issues ------------------------ -* Doesn't currently work with retina display enabled -* Mac Version doesn't like window resizing \ No newline at end of file +* Doesn't currently work with retina display enabled and running on an iPhone 4 (asserts / crashes about multiple tilesets per layer) +* Mac Version can sometimes create line gaps between tiles when resizing the viewport (No easy-to-reproduce case) \ No newline at end of file diff --git a/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m b/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m index bd87f6d..ee08d68 100755 --- a/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m +++ b/Tests/HKTMXTiledMapTest/HKTMXTiledMapTestLayer.m @@ -47,6 +47,8 @@ -(id) init // prepare scroll stuff #ifdef __IPHONE_OS_VERSION_MAX_ALLOWED self.isTouchEnabled = YES; + // setting this, and running on an iPhone 4 causes a crash / assert + //[[CCDirector sharedDirector] enableRetinaDisplay:YES]; #elif __MAC_OS_X_VERSION_MIN_REQUIRED self.isMouseEnabled = YES; [[CCDirector sharedDirector] setResizeMode:kCCDirectorResize_AutoScale]; diff --git a/cocos2d-extensions-ios.xcodeproj/project.pbxproj b/cocos2d-extensions-ios.xcodeproj/project.pbxproj index 51ddb35..af1ae4e 100755 --- a/cocos2d-extensions-ios.xcodeproj/project.pbxproj +++ b/cocos2d-extensions-ios.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ buildPhases = ( ); dependencies = ( + 1E1EF3F313B9A01600C12616 /* PBXTargetDependency */, 6DA580EE139E3C05004D8D0B /* PBXTargetDependency */, 6DA580F0139E3C05004D8D0B /* PBXTargetDependency */, 6DA580F2139E3C05004D8D0B /* PBXTargetDependency */, @@ -28,6 +29,33 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 1E11750A13B99DB50062E519 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA5775F139C9837004D8D0B /* Default.png */; }; + 1E11750B13B99DB50062E519 /* fps_images.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA57764139C9837004D8D0B /* fps_images.png */; }; + 1E11750C13B99DB50062E519 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA57765139C9837004D8D0B /* Icon-72.png */; }; + 1E11750D13B99DB50062E519 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA57766139C9837004D8D0B /* Icon-Small-50.png */; }; + 1E11750E13B99DB50062E519 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA57767139C9837004D8D0B /* Icon-Small.png */; }; + 1E11750F13B99DB50062E519 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA57768139C9837004D8D0B /* Icon-Small@2x.png */; }; + 1E11751013B99DB50062E519 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA5776A139C9837004D8D0B /* Icon.png */; }; + 1E11751113B99DB50062E519 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA5776B139C9837004D8D0B /* Icon@2x.png */; }; + 1E11751213B99DB50062E519 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 6DA5776E139C9837004D8D0B /* iTunesArtwork */; }; + 1E11751413B99DB50062E519 /* cocos2d_extensions_iosAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DA57772139C9837004D8D0B /* cocos2d_extensions_iosAppDelegate.m */; }; + 1E11751513B99DB50062E519 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DA57779139C9837004D8D0B /* main.m */; }; + 1E11751613B99DB50062E519 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DA5777B139C9837004D8D0B /* RootViewController.m */; }; + 1E11751813B99DB50062E519 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1B60F6022AE0040855A /* CoreGraphics.framework */; }; + 1E11751913B99DB50062E519 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1B80F6022AE0040855A /* Foundation.framework */; }; + 1E11751A13B99DB50062E519 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1BA0F6022AE0040855A /* OpenGLES.framework */; }; + 1E11751B13B99DB50062E519 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1BC0F6022AE0040855A /* QuartzCore.framework */; }; + 1E11751C13B99DB50062E519 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1BE0F6022AE0040855A /* UIKit.framework */; }; + 1E11751D13B99DB50062E519 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640020F83B3EA000B3E49 /* AudioToolbox.framework */; }; + 1E11751E13B99DB50062E519 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640040F83B3EA000B3E49 /* OpenAL.framework */; }; + 1E11751F13B99DB50062E519 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 506EDB87102F4C4000A389B3 /* libz.dylib */; }; + 1E11752013B99DB50062E519 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 506EDBA4102F4C9F00A389B3 /* AVFoundation.framework */; }; + 1E11752113B99DB50062E519 /* libcocos2d libraries.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 506EE05E10304ED200A389B3 /* libcocos2d libraries.a */; }; + 1E1EF3ED13B99FDD00C12616 /* HKTMXTiledMapTestLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E11750213B99C9E0062E519 /* HKTMXTiledMapTestLayer.m */; }; + 1E1EF3EF13B99FFF00C12616 /* HKTMXLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E1174FF13B999960062E519 /* HKTMXLayer.m */; }; + 1E1EF3F113B99FFF00C12616 /* HKTMXTiledMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E1174FC13B994C20062E519 /* HKTMXTiledMap.m */; }; + 1E1EF3F413B9A15D00C12616 /* testmap.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 1E11750413B99C9E0062E519 /* testmap.tmx */; }; + 1E1EF3F513B9A15D00C12616 /* tiles.png in Resources */ = {isa = PBXBuildFile; fileRef = 1E11750513B99C9E0062E519 /* tiles.png */; }; 505574581045D68500A31725 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 506EDBA4102F4C9F00A389B3 /* AVFoundation.framework */; }; 505574591045D68500A31725 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640020F83B3EA000B3E49 /* AudioToolbox.framework */; }; 5055745A1045D68500A31725 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1B60F6022AE0040855A /* CoreGraphics.framework */; }; @@ -639,6 +667,20 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 1E11750813B99DB50062E519 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = 506EE05D10304ED200A389B3; + remoteInfo = "cocos2d libraries"; + }; + 1E1EF3F213B9A01600C12616 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E11750613B99DB50062E519; + remoteInfo = HKTMXTiledMapTest; + }; 506EE1A71030507B00A389B3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -762,6 +804,16 @@ /* Begin PBXFileReference section */ 1D6058910D05DD3D006BFB54 /* ExtensionTestTemplate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExtensionTestTemplate.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E1174F913B994C20062E519 /* HKTMXLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HKTMXLayer.h; sourceTree = ""; }; + 1E1174FB13B994C20062E519 /* HKTMXTiledMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HKTMXTiledMap.h; sourceTree = ""; }; + 1E1174FC13B994C20062E519 /* HKTMXTiledMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKTMXTiledMap.m; sourceTree = ""; }; + 1E1174FD13B994C20062E519 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + 1E1174FF13B999960062E519 /* HKTMXLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKTMXLayer.m; sourceTree = ""; }; + 1E11750113B99C9E0062E519 /* HKTMXTiledMapTestLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HKTMXTiledMapTestLayer.h; sourceTree = ""; }; + 1E11750213B99C9E0062E519 /* HKTMXTiledMapTestLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKTMXTiledMapTestLayer.m; sourceTree = ""; }; + 1E11750413B99C9E0062E519 /* testmap.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = testmap.tmx; sourceTree = ""; }; + 1E11750513B99C9E0062E519 /* tiles.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tiles.png; sourceTree = ""; }; + 1E11752513B99DB50062E519 /* HKTMXTIledMap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HKTMXTIledMap.app; sourceTree = BUILT_PRODUCTS_DIR; }; 504DFC6810AF1739006D82FE /* LICENSE.cocos2d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.cocos2d; sourceTree = ""; }; 506EDB87102F4C4000A389B3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 506EDBA4102F4C9F00A389B3 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; @@ -1265,6 +1317,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1E11751713B99DB50062E519 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E11751813B99DB50062E519 /* CoreGraphics.framework in Frameworks */, + 1E11751913B99DB50062E519 /* Foundation.framework in Frameworks */, + 1E11751A13B99DB50062E519 /* OpenGLES.framework in Frameworks */, + 1E11751B13B99DB50062E519 /* QuartzCore.framework in Frameworks */, + 1E11751C13B99DB50062E519 /* UIKit.framework in Frameworks */, + 1E11751D13B99DB50062E519 /* AudioToolbox.framework in Frameworks */, + 1E11751E13B99DB50062E519 /* OpenAL.framework in Frameworks */, + 1E11751F13B99DB50062E519 /* libz.dylib in Frameworks */, + 1E11752013B99DB50062E519 /* AVFoundation.framework in Frameworks */, + 1E11752113B99DB50062E519 /* libcocos2d libraries.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 506EE05C10304ED200A389B3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1432,10 +1501,42 @@ 6DA580E7139E39D0004D8D0B /* FilesDownloaderTest.app */, 6DA58360139E510B004D8D0B /* CCVideoPlayerTest.app */, 6DA5863013A022E8004D8D0B /* CCSendMessagesTest.app */, + 1E11752513B99DB50062E519 /* HKTMXTIledMap.app */, ); name = Products; sourceTree = ""; }; + 1E1174F813B994C20062E519 /* HKTMXTiledMap */ = { + isa = PBXGroup; + children = ( + 1E1174F913B994C20062E519 /* HKTMXLayer.h */, + 1E1174FF13B999960062E519 /* HKTMXLayer.m */, + 1E1174FB13B994C20062E519 /* HKTMXTiledMap.h */, + 1E1174FC13B994C20062E519 /* HKTMXTiledMap.m */, + 1E1174FD13B994C20062E519 /* README.md */, + ); + path = HKTMXTiledMap; + sourceTree = ""; + }; + 1E11750013B99C9E0062E519 /* HKTMXTiledMapTest */ = { + isa = PBXGroup; + children = ( + 1E11750113B99C9E0062E519 /* HKTMXTiledMapTestLayer.h */, + 1E11750213B99C9E0062E519 /* HKTMXTiledMapTestLayer.m */, + 1E11750313B99C9E0062E519 /* Resources */, + ); + path = HKTMXTiledMapTest; + sourceTree = ""; + }; + 1E11750313B99C9E0062E519 /* Resources */ = { + isa = PBXGroup; + children = ( + 1E11750413B99C9E0062E519 /* testmap.tmx */, + 1E11750513B99C9E0062E519 /* tiles.png */, + ); + path = Resources; + sourceTree = ""; + }; 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( @@ -1649,6 +1750,7 @@ 6DA5775D139C9837004D8D0B /* Tests */ = { isa = PBXGroup; children = ( + 1E11750013B99C9E0062E519 /* HKTMXTiledMapTest */, 6DA5890213A06E25004D8D0B /* FilesDownloaderTest */, 6DA5872913A0355B004D8D0B /* CCScrollLayerTest */, 6DA5868613A02E52004D8D0B /* CCSendMessagesTest */, @@ -1929,6 +2031,7 @@ 6DA57D98139CBD3C004D8D0B /* Extensions */ = { isa = PBXGroup; children = ( + 1E1174F813B994C20062E519 /* HKTMXTiledMap */, 6DA5891213A06E33004D8D0B /* FilesDownloader */, 6DA586A913A0331D004D8D0B /* CCScrollLayer */, 6DA5868A13A02E64004D8D0B /* CCSendMessages */, @@ -2333,6 +2436,24 @@ productReference = 1D6058910D05DD3D006BFB54 /* ExtensionTestTemplate.app */; productType = "com.apple.product-type.application"; }; + 1E11750613B99DB50062E519 /* HKTMXTiledMapTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E11752213B99DB50062E519 /* Build configuration list for PBXNativeTarget "HKTMXTiledMapTest" */; + buildPhases = ( + 1E11750913B99DB50062E519 /* Resources */, + 1E11751313B99DB50062E519 /* Sources */, + 1E11751713B99DB50062E519 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 1E11750713B99DB50062E519 /* PBXTargetDependency */, + ); + name = HKTMXTiledMapTest; + productName = "cocos2d-extensions-ios"; + productReference = 1E11752513B99DB50062E519 /* HKTMXTIledMap.app */; + productType = "com.apple.product-type.application"; + }; 506EE05D10304ED200A389B3 /* cocos2d libraries */ = { isa = PBXNativeTarget; buildConfigurationList = 506EE06410304F0100A389B3 /* Build configuration list for PBXNativeTarget "cocos2d libraries" */; @@ -2524,6 +2645,7 @@ 6DA580C8139E39D0004D8D0B /* FilesDownloaderTest */, 6DA5861113A022E8004D8D0B /* CCSendMessagesTest */, 1D6058900D05DD3D006BFB54 /* Extension Test Template */, + 1E11750613B99DB50062E519 /* HKTMXTiledMapTest */, ); }; /* End PBXProject section */ @@ -2545,6 +2667,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1E11750913B99DB50062E519 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E1EF3F413B9A15D00C12616 /* testmap.tmx in Resources */, + 1E1EF3F513B9A15D00C12616 /* tiles.png in Resources */, + 1E11750A13B99DB50062E519 /* Default.png in Resources */, + 1E11750B13B99DB50062E519 /* fps_images.png in Resources */, + 1E11750C13B99DB50062E519 /* Icon-72.png in Resources */, + 1E11750D13B99DB50062E519 /* Icon-Small-50.png in Resources */, + 1E11750E13B99DB50062E519 /* Icon-Small.png in Resources */, + 1E11750F13B99DB50062E519 /* Icon-Small@2x.png in Resources */, + 1E11751013B99DB50062E519 /* Icon.png in Resources */, + 1E11751113B99DB50062E519 /* Icon@2x.png in Resources */, + 1E11751213B99DB50062E519 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6DA57DB3139CBD74004D8D0B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2890,6 +3030,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1E11751313B99DB50062E519 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E1EF3EF13B99FFF00C12616 /* HKTMXLayer.m in Sources */, + 1E1EF3F113B99FFF00C12616 /* HKTMXTiledMap.m in Sources */, + 1E1EF3ED13B99FDD00C12616 /* HKTMXTiledMapTestLayer.m in Sources */, + 1E11751413B99DB50062E519 /* cocos2d_extensions_iosAppDelegate.m in Sources */, + 1E11751513B99DB50062E519 /* main.m in Sources */, + 1E11751613B99DB50062E519 /* RootViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 506EE05B10304ED200A389B3 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3084,6 +3237,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 1E11750713B99DB50062E519 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 506EE05D10304ED200A389B3 /* cocos2d libraries */; + targetProxy = 1E11750813B99DB50062E519 /* PBXContainerItemProxy */; + }; + 1E1EF3F313B9A01600C12616 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E11750613B99DB50062E519 /* HKTMXTiledMapTest */; + targetProxy = 1E1EF3F213B9A01600C12616 /* PBXContainerItemProxy */; + }; 506EE1A81030507B00A389B3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 506EE05D10304ED200A389B3 /* cocos2d libraries */; @@ -3237,6 +3400,52 @@ }; name = Release; }; + 1E11752313B99DB50062E519 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Tests/SharedSources/cocos2d_extensions_ios_Prefix.pch; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + INFOPLIST_FILE = Tests/SharedResources/Info.plist; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PREBINDING = NO; + PRODUCT_NAME = HKTMXTIledMap; + WARNING_CFLAGS = "-Wall"; + }; + name = Debug; + }; + 1E11752413B99DB50062E519 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Tests/SharedSources/cocos2d_extensions_ios_Prefix.pch; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + INFOPLIST_FILE = Tests/SharedResources/Info.plist; + ONLY_ACTIVE_ARCH = NO; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PREBINDING = NO; + PRODUCT_NAME = HKTMXTIledMap; + WARNING_CFLAGS = "-Wall"; + }; + name = Release; + }; 506EE05F10304ED500A389B3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3714,6 +3923,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 1E11752213B99DB50062E519 /* Build configuration list for PBXNativeTarget "HKTMXTiledMapTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E11752313B99DB50062E519 /* Debug */, + 1E11752413B99DB50062E519 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 506EE06410304F0100A389B3 /* Build configuration list for PBXNativeTarget "cocos2d libraries" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/cocos2d-extensions-mac.xcodeproj/project.pbxproj b/cocos2d-extensions-mac.xcodeproj/project.pbxproj index 94138ac..5291fc0 100644 --- a/cocos2d-extensions-mac.xcodeproj/project.pbxproj +++ b/cocos2d-extensions-mac.xcodeproj/project.pbxproj @@ -27,6 +27,25 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 1E1EF41D13B9A99F00C12616 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6DA575D0139C96AE004D8D0B /* InfoPlist.strings */; }; + 1E1EF41E13B9A99F00C12616 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6DA575D2139C96AE004D8D0B /* MainMenu.xib */; }; + 1E1EF41F13B9A99F00C12616 /* fps_images.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DA575D4139C96AE004D8D0B /* fps_images.png */; }; + 1E1EF42013B9A99F00C12616 /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 6DA575D9139C96AE004D8D0B /* icon.icns */; }; + 1E1EF42213B9A99F00C12616 /* cocos2d_extensions_macAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DA575E5139C96AE004D8D0B /* cocos2d_extensions_macAppDelegate.m */; }; + 1E1EF42313B9A99F00C12616 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DA575E9139C96AE004D8D0B /* main.m */; }; + 1E1EF42513B9A99F00C12616 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + 1E1EF42613B9A99F00C12616 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E036A79C121B5C720037C5C6 /* OpenGL.framework */; }; + 1E1EF42713B9A99F00C12616 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E036A79E121B5C870037C5C6 /* QuartzCore.framework */; }; + 1E1EF42813B9A99F00C12616 /* libcocos2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E01E663D121CA00A001A484F /* libcocos2d.a */; }; + 1E1EF42913B9A99F00C12616 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E01E6A3D121EDCD3001A484F /* ApplicationServices.framework */; }; + 1E1EF42A13B9A99F00C12616 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E0F9256D1224207200EF2362 /* libz.dylib */; }; + 1E1EF42B13B9A99F00C12616 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E08AA04A12C0EDC8000341BD /* OpenAL.framework */; }; + 1E1EF42C13B9A99F00C12616 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E08AA04C12C0EEC0000341BD /* AudioToolbox.framework */; }; + 1E1EF43213B9A9F000C12616 /* HKTMXLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E1EF41513B9A96200C12616 /* HKTMXLayer.m */; }; + 1E1EF43313B9A9F000C12616 /* HKTMXTiledMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E1EF41713B9A96200C12616 /* HKTMXTiledMap.m */; }; + 1E1EF43413B9A9F000C12616 /* HKTMXTiledMapTestLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E1EF40E13B9A95A00C12616 /* HKTMXTiledMapTestLayer.m */; }; + 1E1EF43513B9AA0100C12616 /* testmap.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 1E1EF41013B9A95A00C12616 /* testmap.tmx */; }; + 1E1EF43613B9AA0100C12616 /* tiles.png in Resources */ = {isa = PBXBuildFile; fileRef = 1E1EF41113B9A95A00C12616 /* tiles.png */; }; 6D7F4F6F13A27ECE0022601B /* horizontalTestButton-hd.png in Resources */ = {isa = PBXBuildFile; fileRef = 6D7F4F6113A27ECE0022601B /* horizontalTestButton-hd.png */; }; 6D7F4F7013A27ECE0022601B /* horizontalTestButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 6D7F4F6213A27ECE0022601B /* horizontalTestButton.png */; }; 6D7F4F7113A27ECE0022601B /* priorityFour-hd.png in Resources */ = {isa = PBXBuildFile; fileRef = 6D7F4F6313A27ECE0022601B /* priorityFour-hd.png */; }; @@ -533,6 +552,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 1E1EF41B13B9A99F00C12616 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = E01E663C121CA00A001A484F; + remoteInfo = cocos2d; + }; 6D7F521313A2E2B90022601B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -643,6 +669,16 @@ /* Begin PBXFileReference section */ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; + 1E1EF40D13B9A95A00C12616 /* HKTMXTiledMapTestLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HKTMXTiledMapTestLayer.h; sourceTree = ""; }; + 1E1EF40E13B9A95A00C12616 /* HKTMXTiledMapTestLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKTMXTiledMapTestLayer.m; sourceTree = ""; }; + 1E1EF41013B9A95A00C12616 /* testmap.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = testmap.tmx; sourceTree = ""; }; + 1E1EF41113B9A95A00C12616 /* tiles.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tiles.png; sourceTree = ""; }; + 1E1EF41413B9A96200C12616 /* HKTMXLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HKTMXLayer.h; sourceTree = ""; }; + 1E1EF41513B9A96200C12616 /* HKTMXLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKTMXLayer.m; sourceTree = ""; }; + 1E1EF41613B9A96200C12616 /* HKTMXTiledMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HKTMXTiledMap.h; sourceTree = ""; }; + 1E1EF41713B9A96200C12616 /* HKTMXTiledMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKTMXTiledMap.m; sourceTree = ""; }; + 1E1EF41813B9A96200C12616 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + 1E1EF43013B9A9A000C12616 /* HKTMXTIledMap Test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HKTMXTIledMap Test.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 6D7F4F6113A27ECE0022601B /* horizontalTestButton-hd.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "horizontalTestButton-hd.png"; sourceTree = ""; }; @@ -1110,6 +1146,21 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 1E1EF42413B9A99F00C12616 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E1EF42513B9A99F00C12616 /* Cocoa.framework in Frameworks */, + 1E1EF42613B9A99F00C12616 /* OpenGL.framework in Frameworks */, + 1E1EF42713B9A99F00C12616 /* QuartzCore.framework in Frameworks */, + 1E1EF42813B9A99F00C12616 /* libcocos2d.a in Frameworks */, + 1E1EF42913B9A99F00C12616 /* ApplicationServices.framework in Frameworks */, + 1E1EF42A13B9A99F00C12616 /* libz.dylib in Frameworks */, + 1E1EF42B13B9A99F00C12616 /* OpenAL.framework in Frameworks */, + 1E1EF42C13B9A99F00C12616 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6DA57CA2139CAE19004D8D0B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1273,10 +1324,42 @@ 6DA5817F139E3D04004D8D0B /* FilesDownloaderTest.app */, 6DA5865013A0232C004D8D0B /* CCSendMessagesTest.app */, E076E5C01225E97900DE0DA2 /* ExtensionTestTemplate.app */, + 1E1EF43013B9A9A000C12616 /* HKTMXTIledMap Test.app */, ); name = Products; sourceTree = ""; }; + 1E1EF40C13B9A95A00C12616 /* HKTMXTiledMapTest */ = { + isa = PBXGroup; + children = ( + 1E1EF40D13B9A95A00C12616 /* HKTMXTiledMapTestLayer.h */, + 1E1EF40E13B9A95A00C12616 /* HKTMXTiledMapTestLayer.m */, + 1E1EF40F13B9A95A00C12616 /* Resources */, + ); + path = HKTMXTiledMapTest; + sourceTree = ""; + }; + 1E1EF40F13B9A95A00C12616 /* Resources */ = { + isa = PBXGroup; + children = ( + 1E1EF41013B9A95A00C12616 /* testmap.tmx */, + 1E1EF41113B9A95A00C12616 /* tiles.png */, + ); + path = Resources; + sourceTree = ""; + }; + 1E1EF41313B9A96200C12616 /* HKTMXTiledMap */ = { + isa = PBXGroup; + children = ( + 1E1EF41413B9A96200C12616 /* HKTMXLayer.h */, + 1E1EF41513B9A96200C12616 /* HKTMXLayer.m */, + 1E1EF41613B9A96200C12616 /* HKTMXTiledMap.h */, + 1E1EF41713B9A96200C12616 /* HKTMXTiledMap.m */, + 1E1EF41813B9A96200C12616 /* README.md */, + ); + path = HKTMXTiledMap; + sourceTree = ""; + }; 29B97314FDCFA39411CA2CEA /* cocos2d-mac */ = { isa = PBXGroup; children = ( @@ -1474,6 +1557,7 @@ 6DA575CD139C96AE004D8D0B /* Tests */ = { isa = PBXGroup; children = ( + 1E1EF40C13B9A95A00C12616 /* HKTMXTiledMapTest */, 6DA588A913A05EA1004D8D0B /* FilesDownloaderTest */, 6DA5866213A0295D004D8D0B /* CCSendMessagesTest */, 6DA58584139E8027004D8D0B /* CCSliderTest */, @@ -1733,6 +1817,7 @@ 6DA57C7D139CAAB6004D8D0B /* Extensions */ = { isa = PBXGroup; children = ( + 1E1EF41313B9A96200C12616 /* HKTMXTiledMap */, 6DA5888713A05D20004D8D0B /* FilesDownloader */, 6DA5865413A0237E004D8D0B /* CCSendMessages */, 6DA5857E139E8016004D8D0B /* CCSlider */, @@ -2091,6 +2176,26 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 1E1EF41913B9A99F00C12616 /* HKTMXTiledMap Test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E1EF42D13B9A99F00C12616 /* Build configuration list for PBXNativeTarget "HKTMXTiledMap Test" */; + buildPhases = ( + 1E1EF41C13B9A99F00C12616 /* Resources */, + 1E1EF42113B9A99F00C12616 /* Sources */, + 1E1EF42413B9A99F00C12616 /* Frameworks */, + ); + buildRules = ( + ); + comments = "Use this target as a template for test targets.\nDon't build this target itself - it will give you compiler error: \n\tUndefined symbols:\n \t\"_OBJC_CLASS_$_ExtensionTest\", referenced from:\n \tobjc-class-ref-to-ExtensionTest in cocos2d_extensions_macAppDelegate.o\n\tld: symbol(s) not found\n\tclang: error: linker command failed with exit code 1 (use -v to see invocation)\n\nIf you get this error in your extension test target - you forgot to:\n#import \"ExtensionTest.h\"\n\nSYNTHESIZE_EXTENSION_TEST(DemoMenu)\n\n"; + dependencies = ( + 1E1EF41A13B9A99F00C12616 /* PBXTargetDependency */, + ); + name = "HKTMXTiledMap Test"; + productInstallPath = "$(HOME)/Applications"; + productName = "cocos2d-mac"; + productReference = 1E1EF43013B9A9A000C12616 /* HKTMXTIledMap Test.app */; + productType = "com.apple.product-type.application"; + }; 6DA57C96139CAE19004D8D0B /* CCMenuAdvancedTest */ = { isa = PBXNativeTarget; buildConfigurationList = 6DA57CAB139CAE19004D8D0B /* Build configuration list for PBXNativeTarget "CCMenuAdvancedTest" */; @@ -2295,11 +2400,25 @@ 6DA58168139E3D04004D8D0B /* FilesDownloaderTest */, 6DA5863913A0232C004D8D0B /* CCSendMessagesTest */, E076E4F01225E97900DE0DA2 /* Extension Test Template */, + 1E1EF41913B9A99F00C12616 /* HKTMXTiledMap Test */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 1E1EF41C13B9A99F00C12616 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E1EF43513B9AA0100C12616 /* testmap.tmx in Resources */, + 1E1EF43613B9AA0100C12616 /* tiles.png in Resources */, + 1E1EF41D13B9A99F00C12616 /* InfoPlist.strings in Resources */, + 1E1EF41E13B9A99F00C12616 /* MainMenu.xib in Resources */, + 1E1EF41F13B9A99F00C12616 /* fps_images.png in Resources */, + 1E1EF42013B9A99F00C12616 /* icon.icns in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6DA57C99139CAE19004D8D0B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2593,6 +2712,18 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 1E1EF42113B9A99F00C12616 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E1EF43213B9A9F000C12616 /* HKTMXLayer.m in Sources */, + 1E1EF43313B9A9F000C12616 /* HKTMXTiledMap.m in Sources */, + 1E1EF43413B9A9F000C12616 /* HKTMXTiledMapTestLayer.m in Sources */, + 1E1EF42213B9A99F00C12616 /* cocos2d_extensions_macAppDelegate.m in Sources */, + 1E1EF42313B9A99F00C12616 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6DA57C9E139CAE19004D8D0B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2772,6 +2903,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 1E1EF41A13B9A99F00C12616 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E01E663C121CA00A001A484F /* cocos2d */; + targetProxy = 1E1EF41B13B9A99F00C12616 /* PBXContainerItemProxy */; + }; 6D7F521413A2E2B90022601B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6DA5863913A0232C004D8D0B /* CCSendMessagesTest */; @@ -2869,6 +3005,39 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 1E1EF42E13B9A99F00C12616 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Tests/SharedSources/cocos2d_extensions_mac_Prefix.pch; + INFOPLIST_FILE = "Tests/SharedResources/Info-Mac.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + PRODUCT_NAME = "HKTMXTIledMap Test"; + }; + name = Debug; + }; + 1E1EF42F13B9A99F00C12616 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Tests/SharedSources/cocos2d_extensions_mac_Prefix.pch; + INFOPLIST_FILE = "Tests/SharedResources/Info-Mac.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + PRODUCT_NAME = "HKTMXTIledMap Test"; + }; + name = Release; + }; 6DA57CAC139CAE19004D8D0B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3222,6 +3391,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 1E1EF42D13B9A99F00C12616 /* Build configuration list for PBXNativeTarget "HKTMXTiledMap Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E1EF42E13B9A99F00C12616 /* Debug */, + 1E1EF42F13B9A99F00C12616 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 6DA57CAB139CAE19004D8D0B /* Build configuration list for PBXNativeTarget "CCMenuAdvancedTest" */ = { isa = XCConfigurationList; buildConfigurations = ( From 888f0749d16ee37ea3e496648f60443cc05a575c Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Thu, 14 Jul 2011 18:52:24 -0700 Subject: [PATCH 03/13] Fixed HKTMXLayer to work with Retina Display --- Extensions/HKTMXTiledMap/HKTMXLayer.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 889ec7b..2781d56 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -71,7 +71,7 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn if((self=[super init])) { texture_ = [[CCTextureCache sharedTextureCache] addImage:tilesetInfo.sourceImage]; - tilesetInfo.imageSize = texture_.contentSize; + tilesetInfo.imageSize = texture_.contentSizeInPixels; // layerInfo layerName_ = [layerInfo.name copy]; @@ -96,9 +96,9 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn // offset (after layer orientation is set); CGPoint offset = [self calculateLayerOffset:layerInfo.offset]; - [self setPosition:offset]; + [self setPositionInPixels:offset]; - [self setContentSize: CGSizeMake( layerSize_.width * mapTileSize_.width, layerSize_.height * mapTileSize_.height )]; + [self setContentSizeInPixels: CGSizeMake( layerSize_.width * mapTileSize_.width, layerSize_.height * mapTileSize_.height )]; // adjust and validate tile IDs NSAssert1(minGID_ <= maxGID_ + 1 && maxGID_ - minGID_ < 1000000, @@ -113,7 +113,7 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn @"TMX: Only one tileset per layer is supported"); } - CGSize screenSize = [CCDirector sharedDirector].winSize; + CGSize screenSize = [CCDirector sharedDirector].winSizeInPixels; screenGridSize_.width = ceil(screenSize.width / mapTileSize_.width) + 1; screenGridSize_.height = ceil(screenSize.height / mapTileSize_.height) + 1; int screenTileCount = screenGridSize_.width * screenGridSize_.height; From df0fb465e17b07828b77c5b8087e9480aa841951 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Thu, 9 Feb 2012 22:43:11 -0800 Subject: [PATCH 04/13] Integrated Jonathan Barnes's support for flipped tiles --- Extensions/HKTMXTiledMap/HKTMXLayer.h | 26 +++- Extensions/HKTMXTiledMap/HKTMXLayer.m | 162 +++++++++++++++++++---- Extensions/HKTMXTiledMap/HKTMXTiledMap.m | 6 +- 3 files changed, 165 insertions(+), 29 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h index a66d613..dd01b45 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.h +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -33,6 +33,14 @@ */ #import "CCNode.h" +// JEB Bits on the far end of the 32-bit global tile ID (GID's) are used for tile flags +#define kFlippedHorizontallyFlag 0x80000000 +#define kFlippedVerticallyFlag 0x40000000 +#define kFlippedDiagonallyFlag 0x20000000 +#define kFlippedMask ~(kFlippedHorizontallyFlag|kFlippedVerticallyFlag|kFlippedDiagonallyFlag) + + + @class CCTMXMapInfo; @class CCTMXLayerInfo; @class CCTMXTilesetInfo; @@ -60,7 +68,7 @@ struct HKTMXAnimCacheEntry { double validUntil; }; -@interface HKTMXLayer : CCNode +@interface HKTMXLayer : CCNode { CCTMXTilesetInfo *tileset_; CCTexture2D *texture_; @@ -70,7 +78,7 @@ struct HKTMXAnimCacheEntry { CGSize screenGridSize_; unsigned int *tiles_; NSMutableArray *properties_; - unsigned char opacity_; + unsigned int minGID_; unsigned int maxGID_; GLuint buffers_[3]; @@ -82,7 +90,14 @@ struct HKTMXAnimCacheEntry { struct HKTMXAnimRule *animRules_; struct HKTMXAnimCacheEntry *animCache_; double animClock_; + + GLubyte opacity_; + ccColor3B color_; + ccBlendFunc blendFunc_; } + + + /** name of the layer */ @property (nonatomic,readwrite,retain) NSString *layerName; /** size of the layer in tiles */ @@ -126,4 +141,11 @@ struct HKTMXAnimCacheEntry { /** Creates the tiles */ -(void) setupTiles; +/** CCRGBAProtocol protocol */ +@property (nonatomic,readwrite) GLubyte opacity; +@property (nonatomic,readwrite) ccColor3B color; + +/** CCBlendProtocol protocol */ +@property (nonatomic,readwrite) ccBlendFunc blendFunc; + @end diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 2781d56..8797871 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -38,6 +38,8 @@ #import "CCTextureCache.h" #import "CCDirector.h" #import "CGPointExtension.h" +#import "ccMacros.h" +#import "CCSprite.h" #pragma mark - #pragma mark HKTMXLayer @@ -58,6 +60,9 @@ @implementation HKTMXLayer @synthesize layerOrientation=layerOrientation_; @synthesize mapTileSize=mapTileSize_; @synthesize properties=properties_; +@synthesize opacity=opacity_; +@synthesize color=color_; +@synthesize blendFunc = blendFunc_; #pragma mark CCTMXLayer - init & alloc & dealloc @@ -70,6 +75,16 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn { if((self=[super init])) { + // JEB - default blend function + blendFunc_ = (ccBlendFunc) { CC_BLEND_SRC, CC_BLEND_DST }; + + // JEB - default colour + color_.r = 255; + color_.g = 255; + color_.b = 255; + + + texture_ = [[CCTextureCache sharedTextureCache] addImage:tilesetInfo.sourceImage]; tilesetInfo.imageSize = texture_.contentSizeInPixels; @@ -109,13 +124,16 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn #ifdef __BIG_ENDIAN__ tiles_[i] = CFSwapInt32(tiles_[i]); #endif - NSAssert(tiles_[i] == 0 || (tiles_[i] >= minGID_ && tiles_[i] <= maxGID_), + + // JEB flip bits masked to compare true GID + NSAssert((tiles_[i] & kFlippedMask) == 0 || + (((tiles_[i] & kFlippedMask) >= minGID_) && ((tiles_[i] & kFlippedMask) <= maxGID_)), @"TMX: Only one tileset per layer is supported"); } CGSize screenSize = [CCDirector sharedDirector].winSizeInPixels; - screenGridSize_.width = ceil(screenSize.width / mapTileSize_.width) + 1; - screenGridSize_.height = ceil(screenSize.height / mapTileSize_.height) + 1; + screenGridSize_.width = (ceil(screenSize.width / mapTileSize_.width)*2) + 1; + screenGridSize_.height = (ceil(screenSize.height / mapTileSize_.height)*2) + 1; int screenTileCount = screenGridSize_.width * screenGridSize_.height; // create buffer objects glGenBuffers(3, buffers_); @@ -279,12 +297,39 @@ -(void) parseInternalProperties #pragma mark CCTMXLayer - obtaining tiles/gids --(unsigned int) tileGIDAt:(CGPoint)pos + +// JEB - Returns the texture of gid at position as a CCSprite. +-(CCSprite*) tileAt:(CGPoint)pos +{ + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); + //NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released"); + + CCSprite *tile = nil; + uint32_t gid = [self tileGIDAt:pos]; + + // if GID == 0, then no tile is present + if( gid ) + { + + CGRect rect = [tileset_ rectForGID:gid]; + tile = [CCSprite spriteWithTexture:texture_ rect:rect]; + [tile setPositionInPixels: [self positionAt:pos]]; + tile.anchorPoint = CGPointZero; + [tile setOpacity:opacity_]; + } + return tile; +} + + +-(uint32_t) tileGIDAt:(CGPoint)pos { NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); +// NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released"); - int idx = pos.x + (int)pos.y * (int)layerSize_.width; - return tiles_[idx]; + NSInteger idx = pos.x + pos.y * layerSize_.width; + + // JEB - Return true GID + return (tiles_[ idx ] & kFlippedMask); } #pragma mark CCTMXLayer - adding / remove tiles @@ -350,6 +395,19 @@ -(CGPoint) positionForOrthoAt:(CGPoint)pos -(void) draw { + // JEB Set Blend mode + BOOL newBlend = ((blendFunc_.src != CC_BLEND_SRC) || (blendFunc_.dst != CC_BLEND_DST)); + if( newBlend ) + { + glBlendFunc( blendFunc_.src, blendFunc_.dst ); + } + else if( opacity_ != 255 ) + { + newBlend = YES; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glBindTexture(GL_TEXTURE_2D, texture_.name); // TODO: Do we EVER want a tiled map to be anti-aliased? ccTexParams texParams = { GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE }; @@ -381,6 +439,10 @@ -(void) draw GLfloat *texcoords = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); GLushort *indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); #endif + + + + CGSize texSize = tileset_.imageSize; for (int y=0; y < screenGridSize_.height; y++) { @@ -395,32 +457,36 @@ -(void) draw unsigned int tile = tiles_[tileidx]; if (!tile) continue; unsigned int showtile; - if (AC[tile].validUntil <= animClock_) + + // *** JEB index does not included flip bits *** + unsigned int tile_noflags = (tile & kFlippedMask); + if (AC[tile_noflags].validUntil <= animClock_) { - if (AR[tile].last && animClock_ >= AR[tile].cycleTime) + if (AR[tile_noflags].last && animClock_ >= AR[tile].cycleTime) { - showtile = AR[tile].last; - AC[tile].state = showtile; - AC[tile].validUntil = INFINITY; + showtile = AR[tile_noflags].last; + AC[tile_noflags].state = showtile; + AC[tile_noflags].validUntil = INFINITY; } else { - double phase = AR[tile].last ? animClock_ : fmod(animClock_, AR[tile].cycleTime); + double phase = AR[tile_noflags].last ? animClock_ : fmod(animClock_, AR[tile_noflags].cycleTime); showtile = tile; while (phase > AR[showtile].delay) { phase -= AR[showtile].delay; showtile = AR[showtile].next; } - AC[tile].state = showtile; - AC[tile].validUntil = animClock_ + AR[showtile].delay - phase; + AC[tile_noflags].state = showtile; + AC[tile_noflags].validUntil = animClock_ + AR[showtile].delay - phase; } } else - showtile = AC[tile].state; - dirtyAt_ = MIN(dirtyAt_, AC[tile].validUntil); + showtile = AC[tile_noflags].state; + + dirtyAt_ = MIN(dirtyAt_, AC[tile_noflags].validUntil); int screenidx = y * screenGridSize_.width + x; - CGRect tileTexture = [tileset_ rectForGID:showtile]; + CGRect tileTexture = [tileset_ rectForGID:(showtile & kFlippedMask)]; tileTexture.origin.x /= texSize.width; tileTexture.origin.y /= texSize.height; tileTexture.size.width /= texSize.width; @@ -429,14 +495,46 @@ -(void) draw GLushort *idxbase = indices + vertexCount; int vertexbase = screenidx * 4; - texbase[0] = tileTexture.origin.x; - texbase[1] = tileTexture.origin.y + tileTexture.size.height; - texbase[2] = tileTexture.origin.x + tileTexture.size.width; - texbase[3] = tileTexture.origin.y + tileTexture.size.height; - texbase[4] = tileTexture.origin.x; - texbase[5] = tileTexture.origin.y; - texbase[6] = tileTexture.origin.x + tileTexture.size.width; - texbase[7] = tileTexture.origin.y; + // **************************************** + // * JEB Handle flipped and rotated tiles * + // **************************************** + float left, right, top, bottom; + left = tileTexture.origin.x; + right = left + tileTexture.size.width; + bottom = tileTexture.origin.y; + top = bottom + tileTexture.size.height; + + + if (tile & kFlippedVerticallyFlag) + CC_SWAP(top,bottom); + + if (tile & kFlippedHorizontallyFlag) + CC_SWAP(left,right); + + + if (tile & kFlippedDiagonallyFlag) + { + texbase[0] = left; + texbase[1] = top; + texbase[2] = left; + texbase[3] = bottom; + texbase[4] = right; + texbase[5] = top; + texbase[6] = right; + texbase[7] = bottom; + } + else + { + texbase[0] = left; + texbase[1] = top; + texbase[2] = right; + texbase[3] = top; + texbase[4] = left; + texbase[5] = bottom; + texbase[6] = right; + texbase[7] = bottom; + } + // ***************************** idxbase[0] = vertexbase; idxbase[1] = vertexbase + 1; @@ -458,10 +556,14 @@ -(void) draw lastVertexCount_ = vertexCount; texdone: + glPushMatrix(); glTranslatef(baseTile.x * mapTileSize_.width, baseTile.y * mapTileSize_.height, 0); glDisableClientState(GL_COLOR_ARRAY); - glColor4f(1, 1, 1, 1); + + // JEB set layer tint and opacity + glColor4f(color_.r/255.0f, color_.g/255.0f, color_.b/255.0f, opacity_/255.0f); + glTexCoordPointer(2, GL_FLOAT, 0, NULL); glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, NULL); glEnableClientState(GL_COLOR_ARRAY); @@ -469,7 +571,15 @@ -(void) draw glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // JEB - Restore default blend + if( newBlend ) + glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST); + + + } + @end diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m index b00b7eb..9018771 100644 --- a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m +++ b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m @@ -146,10 +146,14 @@ -(CCTMXTilesetInfo*) tilesetForLayer:(CCTMXLayerInfo*)layerInfo map:(CCTMXMapInf // XXX: gid == 0 --> empty tile if( gid != 0 ) { + + // JEB - Mask out flip bits to allow individual layers to have + // different tileset. + gid &= kFlippedMask; // Optimization: quick return // if the layer is invalid (more than 1 tileset per layer) an assert will be thrown later - if( gid >= tileset.firstGid ) + if( (gid & kFlippedMask) >= tileset.firstGid ) return tileset; } } From 803083788f4af8d8c16b22d8ccd967670cbd1176 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Thu, 9 Feb 2012 22:48:48 -0800 Subject: [PATCH 05/13] * credit where credit is due * updated known issues --- Extensions/HKTMXTiledMap/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Extensions/HKTMXTiledMap/README.md b/Extensions/HKTMXTiledMap/README.md index 016fe13..1579b23 100644 --- a/Extensions/HKTMXTiledMap/README.md +++ b/Extensions/HKTMXTiledMap/README.md @@ -20,5 +20,8 @@ Created just like a CCTMXTiledMap. Known issues ------------------------ -* Doesn't currently work with retina display enabled and running on an iPhone 4 (asserts / crashes about multiple tilesets per layer) -* Mac Version can sometimes create line gaps between tiles when resizing the viewport (No easy-to-reproduce case) \ No newline at end of file +* Can sometimes create line gaps between tiles when resizing the viewport (No easy-to-reproduce case) + +Thanks +------------------------ +Special thanks to Jonathan Barnes for adding support for flipped tiles \ No newline at end of file From 381645387fde141c966dd413b3bda4a73d47521d Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Thu, 9 Feb 2012 23:18:23 -0800 Subject: [PATCH 06/13] Fixed broken animation code --- Extensions/HKTMXTiledMap/HKTMXLayer.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 8797871..c5c1ef2 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -462,7 +462,7 @@ -(void) draw unsigned int tile_noflags = (tile & kFlippedMask); if (AC[tile_noflags].validUntil <= animClock_) { - if (AR[tile_noflags].last && animClock_ >= AR[tile].cycleTime) + if (AR[tile_noflags].last && animClock_ >= AR[tile_noflags].cycleTime) { showtile = AR[tile_noflags].last; AC[tile_noflags].state = showtile; @@ -471,7 +471,7 @@ -(void) draw else { double phase = AR[tile_noflags].last ? animClock_ : fmod(animClock_, AR[tile_noflags].cycleTime); - showtile = tile; + showtile = tile_noflags; while (phase > AR[showtile].delay) { phase -= AR[showtile].delay; From 50e14e38df5ec787427ef99a761333a7726ee665 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Fri, 17 Feb 2012 20:34:45 -0800 Subject: [PATCH 07/13] * Fixed platformness of certain code * Make sure we explicitly state we can use tileAt --- Extensions/HKTMXTiledMap/HKTMXLayer.h | 7 ++++++- Extensions/HKTMXTiledMap/HKTMXTiledMap.m | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h index dd01b45..a5fa7c5 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.h +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -31,7 +31,7 @@ * http://www.mapeditor.org * */ -#import "CCNode.h" +#import "cocos2d.h" // JEB Bits on the far end of the 32-bit global tile ID (GID's) are used for tile flags #define kFlippedHorizontallyFlag 0x80000000 @@ -78,6 +78,7 @@ struct HKTMXAnimCacheEntry { CGSize screenGridSize_; unsigned int *tiles_; NSMutableArray *properties_; + int layerOrientation_; unsigned int minGID_; unsigned int maxGID_; @@ -123,6 +124,10 @@ struct HKTMXAnimCacheEntry { */ -(unsigned int) tileGIDAt:(CGPoint)tileCoordinate; +/** returns a sprite that mimics what is at pos. It is up to the user to turn it off or do whatever +*/ +-(CCSprite*) tileAt:(CGPoint)pos; + /** sets the tile gid (gid = tile global id) at a given tile coordinate. The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1. If a tile is already placed at that position, then it will be replaced. diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m index 9018771..9f803db 100644 --- a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m +++ b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m @@ -88,7 +88,12 @@ -(id) initWithTMXFile:(NSString*)tmxFile [self addChild:child z:idx tag:idx]; // update content size with the max size - CGSize childSize = [child contentSize]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED + CGSize childSize = [child contentSize]; +#elif __MAC_OS_X_VERSION_MAX_ALLOWED + NSSize childSize = [child contentSize]; +#endif + CGSize currentSize = [self contentSize]; currentSize.width = MAX( currentSize.width, childSize.width ); currentSize.height = MAX( currentSize.height, childSize.height ); From b9f925147cb8a6bb09173350dd0537b7b95978dc Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Mon, 20 Feb 2012 23:42:14 -0800 Subject: [PATCH 08/13] * Added experimental features tileAt and setTile:At: which allow you similar functionalities to CCTMXTiledMap. These however will penalize performance advantages of using HKTMXTiledMap * Added true support for scaling, so that you can set your max scale, and then work with it from there. Performance degrades the more tiles you draw, per usual, but it should still be better than CCTMXTiledMap * more support for flipped tiles * bug fix in tileAt such that the tile respects flippedness --- .../HKTMXTiledMap/HKTMXLayer+Experimental.h | 54 ++++++ .../HKTMXTiledMap/HKTMXLayer+Experimental.m | 166 ++++++++++++++++++ Extensions/HKTMXTiledMap/HKTMXLayer.h | 34 +++- Extensions/HKTMXTiledMap/HKTMXLayer.m | 96 ++++++---- 4 files changed, 315 insertions(+), 35 deletions(-) create mode 100644 Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.h create mode 100644 Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m mode change 100644 => 100755 Extensions/HKTMXTiledMap/HKTMXLayer.h mode change 100644 => 100755 Extensions/HKTMXTiledMap/HKTMXLayer.m diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.h b/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.h new file mode 100644 index 0000000..1380d69 --- /dev/null +++ b/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.h @@ -0,0 +1,54 @@ +/* + * HKTMXTiledMap + * + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions + * + * HKASoftware + * http://hkasoftware.com + * + * Copyright (c) 2011 HKASoftware + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * TMX Tiled Map support: + * http://www.mapeditor.org + * + */ + +// ***************************************************************************** +// * WARNING - The following functionallity negates the efficiencies provided * +// * by the HKTMX implementation. Because of this, the use of * +// * setTile:at: is not recommended. * +// ***************************************************************************** +#import "HKTMXLayer.h" + + +@class CCSprite; + +@interface HKTMXLayer (Experimental) + +// returns a sprite generated from the texture used at tileCoordinate +-(CCSprite*) tileAt:(CGPoint) tileCoordinate; + +// Adds a tile to the Layer as a sprite +// Note: This will add a performance overhead. +-(void) setTile:(CCSprite *)tile at:(CGPoint) tileCoordinate; + +@end diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m b/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m new file mode 100644 index 0000000..a2b1ae1 --- /dev/null +++ b/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m @@ -0,0 +1,166 @@ +/* + * HKTMXTiledMap + * + * cocos2d-extensions + * https://github.com/cocos2d/cocos2d-iphone-extensions + * + * HKASoftware + * http://hkasoftware.com + * + * Copyright (c) 2011 HKASoftware + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * TMX Tiled Map support: + * http://www.mapeditor.org + * + */ + + +#import "HKTMXLayer+Experimental.h" +#import "CCSprite.h" +#import "CGPointExtension.h" +#import "CCTMXXMLParser.h" +#import "ccMacros.h" + +@implementation HKTMXLayer (Experimental) + +// JEB - Generates a sprite based on the tile at given coords +-(CCSprite*) tileAt:(CGPoint)pos +{ + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); + //NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released"); + + CCSprite *tile = nil; + uint32_t gid = [self tileGIDAt:pos]; + uint32_t flipbits = [self tileFlipBitsAt:pos]; + + // if GID == 0, then no tile is present + if( gid ) + { + + CGRect rect = [tileset_ rectForGID:gid]; + if (CC_CONTENT_SCALE_FACTOR() == 2) + { + // Retina Support + rect.origin.x = (rect.origin.x * 0.5); + rect.origin.y = (rect.origin.y * 0.5); + rect.size.width = (rect.size.width * 0.5); + rect.size.height = (rect.size.height * 0.5); + } + tile = [CCSprite spriteWithTexture:texture_ rect:rect]; + [tile setPositionInPixels: [self positionAt:pos]]; + tile.anchorPoint = CGPointZero; + [tile setOpacity:opacity_]; + + // Test for 90 rotation + if((flipbits & kTileRotated90) == kTileRotated90) + { + tile.rotation = 90; + } + // Test for 270 rotation + else if ((flipbits & kTileRotated270) == kTileRotated270) + { + tile.rotation = 270; + } + else + { + // Normal flipping + if(flipbits & kFlippedHorizontallyFlag) + tile.flipX = YES; + + if(flipbits & kFlippedVerticallyFlag) + tile.flipY = YES; + } + } + return tile; +} + + + +// JEB - Replaces a tilemap tile with a sprite tile +-(void) setTile:(CCSprite *)tile at:(CGPoint) pos +{ + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); + NSAssert( ((tile.contentSizeInPixels.width == mapTileSize_.width) && + (tile.contentSizeInPixels.height == mapTileSize_.height)), @"TMXLayer: invalid tile"); + + // Remove current tile from location + [self removeTileAt:pos]; + + // Set anchor point at center to allow rotaion. + tile.anchorPoint = ccp(0.5f,0.5f); + pos.x += 0.5f; + pos.y -= 0.5f; + + // Position in pixels for retina support + tile.positionInPixels = ccp((pos.x * mapTileSize_.width), (((layerSize_.height -1) * mapTileSize_.height) - pos.y * mapTileSize_.height)); + + // Add sprite to layer via CCNode's addChild method + [super addChild:tile z:zOrder_ tag:0]; +} + + + +// JEB - The following is to aid performance if using "sprite" tiles +-(void) visit +{ + + // Have any "Sprite" tiles been added to the layer + if(children_) + { + ccArray *arrayData = children_->data; + + + CGAffineTransform trans = [self worldToNodeTransform]; + CGPoint baseTile = CGPointMake(floor(trans.tx / mapTileSize_.width), + floor(trans.ty / mapTileSize_.height)); + CGPoint maxTile = CGPointMake((baseTile.x + screenGridSize_.width) , + (baseTile.y + screenGridSize_.height)); + + NSUInteger i = 0; + + // Process each child tile + for( ; i < arrayData->num; i++ ) + { + CCNode *child = arrayData->arr[i]; + + // sprite position always positive so can cast intead of calling floor + CGPoint tileCoord = CGPointMake((int)(child.positionInPixels.x / mapTileSize_.width), + (int)(child.positionInPixels .y / mapTileSize_.width)); + + // Should the tile be actually drawn. + if ((tileCoord.x >= baseTile.x) && (tileCoord.y >= baseTile.y) && + (tileCoord.x < maxTile.x ) && (tileCoord.y < maxTile.y )) + { + child.visible = YES; + } + else + { + child.visible = NO; + } + } + } + + // Ensure CCNode visit is called + [super visit]; +} + + +@end diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h old mode 100644 new mode 100755 index a5fa7c5..1221fc4 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.h +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -31,20 +31,35 @@ * http://www.mapeditor.org * */ -#import "cocos2d.h" +#import "CCNode.h" + + +// JEB - The following define can me used to support scaling out of the tilemap. +// E.g A value of 0.5f will allow the map to be zoomed out upto 2x +// WARNING: Changing this value will impact performance. +#ifndef HKTMX_LAYER_SCALE_LIMIT +#define HKTMX_LAYER_SCALE_LIMIT 1.0f +#endif + // JEB Bits on the far end of the 32-bit global tile ID (GID's) are used for tile flags #define kFlippedHorizontallyFlag 0x80000000 #define kFlippedVerticallyFlag 0x40000000 #define kFlippedDiagonallyFlag 0x20000000 #define kFlippedMask ~(kFlippedHorizontallyFlag|kFlippedVerticallyFlag|kFlippedDiagonallyFlag) +#define kGIDMask (kFlippedHorizontallyFlag|kFlippedVerticallyFlag|kFlippedDiagonallyFlag) +#define kTileRotated0 0x00000000 +#define kTileRotated90 (kFlippedDiagonallyFlag|kFlippedHorizontallyFlag) +#define kTileRotated180 (kFlippedHorizontallyFlag|kFlippedVerticallyFlag) +#define kTileRotated270 (kFlippedDiagonallyFlag|kFlippedVerticallyFlag) @class CCTMXMapInfo; @class CCTMXLayerInfo; @class CCTMXTilesetInfo; + /** Represents a tile animation state. When animClock == 0.0, each tile is in a state equal to its GID. After entering a state, a tile will look up the AnimRule for that @@ -76,6 +91,7 @@ struct HKTMXAnimCacheEntry { CGSize layerSize_; CGSize mapTileSize_; CGSize screenGridSize_; + CGSize zoomGridSize_; unsigned int *tiles_; NSMutableArray *properties_; int layerOrientation_; @@ -124,10 +140,6 @@ struct HKTMXAnimCacheEntry { */ -(unsigned int) tileGIDAt:(CGPoint)tileCoordinate; -/** returns a sprite that mimics what is at pos. It is up to the user to turn it off or do whatever -*/ --(CCSprite*) tileAt:(CGPoint)pos; - /** sets the tile gid (gid = tile global id) at a given tile coordinate. The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1. If a tile is already placed at that position, then it will be replaced. @@ -153,4 +165,16 @@ struct HKTMXAnimCacheEntry { /** CCBlendProtocol protocol */ @property (nonatomic,readwrite) ccBlendFunc blendFunc; +// performance tuning if your map uses a number of scales +// May not be a value < HKTMX_LAYER_SCALE_LIMIT +-(void)updateScale:(float)s; + +// returns of flipbits for tile at tileCoordinate +-(unsigned int) tileFlipBitsAt:(CGPoint) tileCoordinate; + +// sets the flipbits for a tile at given coordinates +-(void) setTileFlipBits:(unsigned int)flipbits at:(CGPoint) tileCoordinate; + + + @end diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m old mode 100644 new mode 100755 index c5c1ef2..0910948 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -73,6 +73,10 @@ +(id) layerWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerI -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo { + // JEB - A layer must have at least one tile to be able to associated a tileset spritesheet with it. + // This tile can be always be cleared with removeTileAt: after initialisation. + NSAssert1((tilesetInfo != nil), @"TMX Layer '%@' has no associated tileset", layerInfo.name); + if((self=[super init])) { // JEB - default blend function @@ -132,8 +136,10 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn } CGSize screenSize = [CCDirector sharedDirector].winSizeInPixels; - screenGridSize_.width = (ceil(screenSize.width / mapTileSize_.width)*2) + 1; - screenGridSize_.height = (ceil(screenSize.height / mapTileSize_.height)*2) + 1; + // JEB - Added support for tilemap scaling + screenGridSize_.width = (ceil(screenSize.width / (mapTileSize_.width * HKTMX_LAYER_SCALE_LIMIT)) + 1); + screenGridSize_.height = (ceil(screenSize.height / (mapTileSize_.height * HKTMX_LAYER_SCALE_LIMIT)) + 1); + zoomGridSize_ = screenGridSize_; int screenTileCount = screenGridSize_.width * screenGridSize_.height; // create buffer objects glGenBuffers(3, buffers_); @@ -298,59 +304,73 @@ -(void) parseInternalProperties #pragma mark CCTMXLayer - obtaining tiles/gids -// JEB - Returns the texture of gid at position as a CCSprite. --(CCSprite*) tileAt:(CGPoint)pos +-(uint32_t) tileGIDAt:(CGPoint)pos { NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); - //NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released"); +// NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released"); - CCSprite *tile = nil; - uint32_t gid = [self tileGIDAt:pos]; + NSInteger idx = pos.x + pos.y * layerSize_.width; - // if GID == 0, then no tile is present - if( gid ) - { - - CGRect rect = [tileset_ rectForGID:gid]; - tile = [CCSprite spriteWithTexture:texture_ rect:rect]; - [tile setPositionInPixels: [self positionAt:pos]]; - tile.anchorPoint = CGPointZero; - [tile setOpacity:opacity_]; - } - return tile; + // JEB - Return true GID + return (tiles_[ idx ] & kFlippedMask); } --(uint32_t) tileGIDAt:(CGPoint)pos + +// JEB - Returns flipbits of tile at coords +-(unsigned int) tileFlipBitsAt:(CGPoint)pos { - NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); -// NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released"); - + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); NSInteger idx = pos.x + pos.y * layerSize_.width; - // JEB - Return true GID - return (tiles_[ idx ] & kFlippedMask); + return (tiles_[ idx ] & kGIDMask); } #pragma mark CCTMXLayer - adding / remove tiles + + + + +// JEB - Change GID at location. Flip bits preserved -(void) setTileGID:(unsigned int)gid at:(CGPoint)pos { NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); NSAssert1(gid == 0 || (gid >= minGID_ && gid <= maxGID_), @"invalid gid (%u) for tileset", gid); int idx = (int)pos.y * (int)layerSize_.width + pos.x; - tiles_[idx] = gid; + unsigned int flipbits = tiles_[idx] & kGIDMask; + tiles_[idx] = flipbits | gid; + dirtyAt_ = -INFINITY; +} + + + +// JEB - Change the flip bits at location +-(void) setTileFlipBits:(unsigned int)flipbits at:(CGPoint)pos +{ + NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); + NSAssert(!((flipbits & kFlippedMask) || ((flipbits & ~kFlippedMask)==~kFlippedMask) ), @"invalid flipbits"); + + + int idx = (int)pos.y * (int)layerSize_.width + pos.x; + unsigned int gid = tiles_[idx] & kFlippedMask; + tiles_[idx] = flipbits | gid; dirtyAt_ = -INFINITY; } + +// JEB - Although sprite tiles can be added though setTile:at: I have left this +// to prevent abuse. -(void) addChild: (CCNode*)node z:(NSInteger)z tag:(NSInteger)tag { NSAssert(NO, @"addChild: is not supported on CCTMXLayer. Instead use setTileGID:at:/tileGIDAt:"); } +// JEB - Ensured both flip bits and GID are cleared. -(void) removeTileAt:(CGPoint)pos { [self setTileGID:0 at:pos]; + [self setTileFlipBits:0 at:pos]; } #pragma mark CCTMXLayer - obtaining positions, offset @@ -393,6 +413,22 @@ -(CGPoint) positionForOrthoAt:(CGPoint)pos #pragma mark CCTMXLayer - draw +// updates grid based on a certain scale. This way you can optimize how much you want to draw. +// this is strictly for performance tuning based on your individual needs +-(void)updateScale:(float)s +{ + if(s >= HKTMX_LAYER_SCALE_LIMIT) + { + CGSize screenSize = [CCDirector sharedDirector].winSizeInPixels; + zoomGridSize_.width = (ceil(screenSize.width / (mapTileSize_.width * s)) + 1); + zoomGridSize_.height = (ceil(screenSize.height / (mapTileSize_.height * s)) + 1); + } + else + { + CCLOG(@"HKTMX: Warning layer scale passed HKTMX_LAYER_SCALE_LIMIT"); + } +} + -(void) draw { // JEB Set Blend mode @@ -421,8 +457,8 @@ -(void) draw glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers_[2]); CGAffineTransform trans = [self worldToNodeTransform]; - CGPoint baseTile = CGPointMake(floor(trans.tx / mapTileSize_.width), - floor(trans.ty / mapTileSize_.height)); + CGPoint baseTile = CGPointMake(floor(trans.tx / (mapTileSize_.width)), + floor(trans.ty / (mapTileSize_.height))); unsigned int vertexCount = 0; if (dirtyAt_ > animClock_ && baseTile.x == lastBaseTile_.x && baseTile.y == lastBaseTile_.y) { @@ -444,11 +480,11 @@ -(void) draw CGSize texSize = tileset_.imageSize; - for (int y=0; y < screenGridSize_.height; y++) + for (int y=0; y < zoomGridSize_.height; y++) { if (baseTile.y + y < 0 || baseTile.y + y >= layerSize_.height) continue; - for (int x=0; x < screenGridSize_.width; x++) + for (int x=0; x < zoomGridSize_.width; x++) { if (baseTile.x + x < 0 || baseTile.x + x >= layerSize_.width) continue; @@ -485,7 +521,7 @@ -(void) draw showtile = AC[tile_noflags].state; dirtyAt_ = MIN(dirtyAt_, AC[tile_noflags].validUntil); - int screenidx = y * screenGridSize_.width + x; + int screenidx = (y * (screenGridSize_.width)) + x; CGRect tileTexture = [tileset_ rectForGID:(showtile & kFlippedMask)]; tileTexture.origin.x /= texSize.width; tileTexture.origin.y /= texSize.height; From aa0f85f5e819c0d125aeda769348c083d986fd2c Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Tue, 21 Feb 2012 23:54:12 -0800 Subject: [PATCH 09/13] Added support for CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL --- Extensions/HKTMXTiledMap/HKTMXLayer.m | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 0910948..3c2415c 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -523,10 +523,7 @@ -(void) draw dirtyAt_ = MIN(dirtyAt_, AC[tile_noflags].validUntil); int screenidx = (y * (screenGridSize_.width)) + x; CGRect tileTexture = [tileset_ rectForGID:(showtile & kFlippedMask)]; - tileTexture.origin.x /= texSize.width; - tileTexture.origin.y /= texSize.height; - tileTexture.size.width /= texSize.width; - tileTexture.size.height /= texSize.height; + GLfloat *texbase = texcoords + screenidx * 4 * 2; GLushort *idxbase = indices + vertexCount; int vertexbase = screenidx * 4; @@ -535,12 +532,20 @@ -(void) draw // * JEB Handle flipped and rotated tiles * // **************************************** float left, right, top, bottom; - left = tileTexture.origin.x; - right = left + tileTexture.size.width; - bottom = tileTexture.origin.y; - top = bottom + tileTexture.size.height; +#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL + left = (2*tileTexture.origin.x + 1) / (2* texSize.width); + right = left + (2*tileTexture.size.width-2)/(2*texSize.width); + bottom = (2*tileTexture.origin.y+1) / (2*texSize.height); + top = bottom + (2*tileTexture.size.height-2)/(2*texSize.height); +#else + left = (tileTexture.origin.x / texSize.width); + right = left + (tileTexture.size.width / texSize.width); + bottom = (tileTexture.origin.y / texSize.width); + top = bottom + (tileTexture.size.height / texSize.width); +#endif + if (tile & kFlippedVerticallyFlag) CC_SWAP(top,bottom); From f6e8007ea317c74a86d055bbb5452f4391bc5f37 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Wed, 21 Mar 2012 22:53:14 -0700 Subject: [PATCH 10/13] * added support for one shot animations via setTileGID --- Extensions/HKTMXTiledMap/HKTMXLayer.m | 30 ++++++++++++++++++++++++++- Extensions/HKTMXTiledMap/README.md | 12 ++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 3c2415c..48a112c 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -205,6 +205,11 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn animRules_[idx].next = next; animCount++; } + else if(delay > 0) + { + animRules_[idx].delay = delay; + } + }]; #else @@ -220,6 +225,10 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn animRules_[idx].next = next; animCount++; } + else if(delay > 0) + { + animRules_[idx].delay = delay; + } } #endif // find animation cycles and annotate @@ -341,6 +350,14 @@ -(void) setTileGID:(unsigned int)gid at:(CGPoint)pos unsigned int flipbits = tiles_[idx] & kGIDMask; tiles_[idx] = flipbits | gid; dirtyAt_ = -INFINITY; + + struct HKTMXAnimRule *AR = animRules_ - minGID_; + struct HKTMXAnimCacheEntry *AC = animCache_ - minGID_; + if(AR[gid].delay && AR[gid].next) + { + AC[gid].state = gid; + AC[gid].validUntil = animClock_ + AR[gid].delay; + } } @@ -502,7 +519,18 @@ -(void) draw { showtile = AR[tile_noflags].last; AC[tile_noflags].state = showtile; - AC[tile_noflags].validUntil = INFINITY; + if(AR[showtile].delay > 0) + { + if(AR[showtile].delay + AC[tile_noflags].validUntil < animClock_) + { + showtile = 0; + [self removeTileAt:ccp(baseTile.x + x, layerSize_.height - (baseTile.y + y + 1))]; + } + } + else + { + AC[tile_noflags].validUntil = INFINITY; + } } else { diff --git a/Extensions/HKTMXTiledMap/README.md b/Extensions/HKTMXTiledMap/README.md index 1579b23..38154d3 100644 --- a/Extensions/HKTMXTiledMap/README.md +++ b/Extensions/HKTMXTiledMap/README.md @@ -8,7 +8,14 @@ Also added to it is animation functionality. This allows you to have data-driven Animation ------------------------ - To animate tiles, you edit tile properties (via Tiled or whatever editor) to have "Next" which lists the next GID in the animation, and Delay (the delay between frames). It supports looped and one shot animations, but all animations have to be deterministic (no random) +To animate tiles, you edit tile properties (via Tiled or whatever editor) to have "Next" which lists the next GID in the animation, and Delay (the delay between frames). +It supports looped and one shot animations, but all animations have to be deterministic (no random) + +For one shot animations: +* If you add a delay, but no Next on the last frame of the animation, then after that delay, it will remove the tile (eg. for an explosion) +* if you do not add a delay, then the last frame will continue on forever without being updated + +It should be noted that if you setatilegid to the start of a one shot animation before the same oneshotanimation finishes (no matter where it is on the map), it will reset the loop for all of them How to create ------------------------ @@ -16,11 +23,10 @@ How to create Maps should be made in Tiled http://www.mapeditor.org Created just like a CCTMXTiledMap. - HKTMXTiledMap* node = [HKTMXTiledMap tiledMapWithTMXFile:@"testmap.tmx"]; +HKTMXTiledMap* node = [HKTMXTiledMap tiledMapWithTMXFile:@"testmap.tmx"]; Known issues ------------------------ -* Can sometimes create line gaps between tiles when resizing the viewport (No easy-to-reproduce case) Thanks ------------------------ From 3e23451d02a763d7d100e95a7511983e3509a846 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Thu, 22 Mar 2012 12:53:15 -0700 Subject: [PATCH 11/13] * Fixed bug involving oneshot animations involving more than 2 frames --- Extensions/HKTMXTiledMap/HKTMXLayer.h | 1 + Extensions/HKTMXTiledMap/HKTMXLayer.m | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h index 1221fc4..fc464bf 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.h +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -79,6 +79,7 @@ struct HKTMXAnimRule { }; struct HKTMXAnimCacheEntry { + double starttime; unsigned int state; double validUntil; }; diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 48a112c..37de158 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -355,6 +355,7 @@ -(void) setTileGID:(unsigned int)gid at:(CGPoint)pos struct HKTMXAnimCacheEntry *AC = animCache_ - minGID_; if(AR[gid].delay && AR[gid].next) { + AC[gid].starttime = animClock_; AC[gid].state = gid; AC[gid].validUntil = animClock_ + AR[gid].delay; } @@ -515,9 +516,10 @@ -(void) draw unsigned int tile_noflags = (tile & kFlippedMask); if (AC[tile_noflags].validUntil <= animClock_) { - if (AR[tile_noflags].last && animClock_ >= AR[tile_noflags].cycleTime) + CGFloat time = animClock_ - AC[tile_noflags].starttime; + if (AR[tile_noflags].last && time >= AR[tile_noflags].cycleTime) { - showtile = AR[tile_noflags].last; + showtile = AR[tile_noflags].last; AC[tile_noflags].state = showtile; if(AR[showtile].delay > 0) { @@ -534,7 +536,7 @@ -(void) draw } else { - double phase = AR[tile_noflags].last ? animClock_ : fmod(animClock_, AR[tile_noflags].cycleTime); + double phase = AR[tile_noflags].last ? animClock_- AC[tile_noflags].starttime : fmod(animClock_, AR[tile_noflags].cycleTime); showtile = tile_noflags; while (phase > AR[showtile].delay) { From bb504664256b8c24234fa8de14f2a3dd735cfdc8 Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Wed, 23 May 2012 21:43:51 -0700 Subject: [PATCH 12/13] * Fixed texture being released inadvertently * Fixed non-squared textures due to stretch by texel * Integrated Jonathan's Barnes support for rotated tiles --- .../HKTMXTiledMap/HKTMXLayer+Experimental.m | 11 +++- Extensions/HKTMXTiledMap/HKTMXLayer.h | 2 + Extensions/HKTMXTiledMap/HKTMXLayer.m | 61 ++++++++++++------- Extensions/HKTMXTiledMap/HKTMXTiledMap.h | 0 Extensions/HKTMXTiledMap/HKTMXTiledMap.m | 0 5 files changed, 49 insertions(+), 25 deletions(-) mode change 100644 => 100755 Extensions/HKTMXTiledMap/HKTMXTiledMap.h mode change 100644 => 100755 Extensions/HKTMXTiledMap/HKTMXTiledMap.m diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m b/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m index a2b1ae1..95d1bc9 100644 --- a/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer+Experimental.m @@ -73,11 +73,18 @@ -(CCSprite*) tileAt:(CGPoint)pos if((flipbits & kTileRotated90) == kTileRotated90) { tile.rotation = 90; + + if(flipbits & kFlippedVerticallyFlag) + tile.flipY = YES; + } // Test for 270 rotation else if ((flipbits & kTileRotated270) == kTileRotated270) { tile.rotation = 270; + + if(flipbits & kFlippedHorizontallyFlag) + tile.flipX = YES; } else { @@ -117,7 +124,7 @@ -(void) setTile:(CCSprite *)tile at:(CGPoint) pos } - +#if 1 // JEB - The following is to aid performance if using "sprite" tiles -(void) visit { @@ -161,6 +168,6 @@ -(void) visit // Ensure CCNode visit is called [super visit]; } - +#endif @end diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.h b/Extensions/HKTMXTiledMap/HKTMXLayer.h index fc464bf..02b01ab 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.h +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.h @@ -46,6 +46,7 @@ #define kFlippedHorizontallyFlag 0x80000000 #define kFlippedVerticallyFlag 0x40000000 #define kFlippedDiagonallyFlag 0x20000000 +#define kFlippedAllFlag 0xE0000000 #define kFlippedMask ~(kFlippedHorizontallyFlag|kFlippedVerticallyFlag|kFlippedDiagonallyFlag) #define kGIDMask (kFlippedHorizontallyFlag|kFlippedVerticallyFlag|kFlippedDiagonallyFlag) @@ -115,6 +116,7 @@ struct HKTMXAnimCacheEntry { } +@property (nonatomic, readonly, retain) CCTexture2D *texture; /** name of the layer */ @property (nonatomic,readwrite,retain) NSString *layerName; diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index 37de158..d78cf61 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -57,6 +57,7 @@ -(void) parseInternalProperties; @implementation HKTMXLayer @synthesize layerSize = layerSize_, layerName = layerName_, tiles=tiles_; @synthesize tileset=tileset_; +@synthesize texture=texture_; @synthesize layerOrientation=layerOrientation_; @synthesize mapTileSize=mapTileSize_; @synthesize properties=properties_; @@ -367,7 +368,7 @@ -(void) setTileGID:(unsigned int)gid at:(CGPoint)pos -(void) setTileFlipBits:(unsigned int)flipbits at:(CGPoint)pos { NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); - NSAssert(!((flipbits & kFlippedMask) || ((flipbits & ~kFlippedMask)==~kFlippedMask) ), @"invalid flipbits"); + int idx = (int)pos.y * (int)layerSize_.width + pos.x; @@ -570,8 +571,8 @@ -(void) draw #else left = (tileTexture.origin.x / texSize.width); right = left + (tileTexture.size.width / texSize.width); - bottom = (tileTexture.origin.y / texSize.width); - top = bottom + (tileTexture.size.height / texSize.width); + bottom = (tileTexture.origin.y / texSize.height); + top = bottom + (tileTexture.size.height / texSize.height); #endif @@ -583,28 +584,42 @@ -(void) draw CC_SWAP(left,right); - if (tile & kFlippedDiagonallyFlag) - { - texbase[0] = left; - texbase[1] = top; - texbase[2] = left; - texbase[3] = bottom; - texbase[4] = right; - texbase[5] = top; - texbase[6] = right; - texbase[7] = bottom; - } - else + switch (tile & kFlippedAllFlag) { - texbase[0] = left; - texbase[1] = top; - texbase[2] = right; - texbase[3] = top; - texbase[4] = left; - texbase[5] = bottom; - texbase[6] = right; - texbase[7] = bottom; + case 0x60000000: + case 0xA0000000: + texbase[0] = left; + texbase[1] = bottom; + texbase[2] = left; + texbase[3] = top; + texbase[4] = right; + texbase[5] = bottom; + texbase[6] = right; + texbase[7] = top; + break; + + case 0xe0000000: + case 0x20000000: + texbase[0] = right; + texbase[1] = top; + texbase[2] = right; + texbase[3] = bottom; + texbase[4] = left; + texbase[5] = top; + texbase[6] = left; + texbase[7] = bottom; + break; + default: + texbase[0] = left; + texbase[1] = top; + texbase[2] = right; + texbase[3] = top; + texbase[4] = left; + texbase[5] = bottom; + texbase[6] = right; + texbase[7] = bottom; } + // ***************************** idxbase[0] = vertexbase; diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.h b/Extensions/HKTMXTiledMap/HKTMXTiledMap.h old mode 100644 new mode 100755 diff --git a/Extensions/HKTMXTiledMap/HKTMXTiledMap.m b/Extensions/HKTMXTiledMap/HKTMXTiledMap.m old mode 100644 new mode 100755 From c4809415337e3c4ea0b7a3f0f5f39431f714d89d Mon Sep 17 00:00:00 2001 From: SkyHawk Date: Sun, 27 May 2012 11:46:05 -0700 Subject: [PATCH 13/13] manually retain / release --- Extensions/HKTMXTiledMap/HKTMXLayer.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/HKTMXTiledMap/HKTMXLayer.m b/Extensions/HKTMXTiledMap/HKTMXLayer.m index d78cf61..68e8b0b 100755 --- a/Extensions/HKTMXTiledMap/HKTMXLayer.m +++ b/Extensions/HKTMXTiledMap/HKTMXLayer.m @@ -90,7 +90,7 @@ -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerIn - texture_ = [[CCTextureCache sharedTextureCache] addImage:tilesetInfo.sourceImage]; + texture_ = [[[CCTextureCache sharedTextureCache] addImage:tilesetInfo.sourceImage] retain]; tilesetInfo.imageSize = texture_.contentSizeInPixels; // layerInfo @@ -277,7 +277,7 @@ - (void) dealloc [layerName_ release]; [tileset_ release]; [properties_ release]; - + [texture_ release]; free(tiles_); free(animRules_); free(animCache_);