summary refs log tree commit diff stats
path: root/libs/cocos2d/CCTMXLayer.m
diff options
context:
space:
mode:
authorStarla Insigna <starla4444@gmail.com>2011-07-30 11:19:14 -0400
committerStarla Insigna <starla4444@gmail.com>2011-07-30 11:19:14 -0400
commit9cd57b731ab1c666d4a1cb725538fdc137763d12 (patch)
tree5bac45ae5157a1cb10c6e45500cbf72789917980 /libs/cocos2d/CCTMXLayer.m
downloadcartcollect-9cd57b731ab1c666d4a1cb725538fdc137763d12.tar.gz
cartcollect-9cd57b731ab1c666d4a1cb725538fdc137763d12.tar.bz2
cartcollect-9cd57b731ab1c666d4a1cb725538fdc137763d12.zip
Initial commit (version 0.2.1)
Diffstat (limited to 'libs/cocos2d/CCTMXLayer.m')
-rwxr-xr-xlibs/cocos2d/CCTMXLayer.m670
1 files changed, 670 insertions, 0 deletions
diff --git a/libs/cocos2d/CCTMXLayer.m b/libs/cocos2d/CCTMXLayer.m new file mode 100755 index 0000000..bb2ba60 --- /dev/null +++ b/libs/cocos2d/CCTMXLayer.m
@@ -0,0 +1,670 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2009-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 *
26 * TMX Tiled Map support:
27 * http://www.mapeditor.org
28 *
29 */
30
31#import "CCTMXLayer.h"
32#import "CCTMXTiledMap.h"
33#import "CCTMXXMLParser.h"
34#import "CCSprite.h"
35#import "CCSpriteBatchNode.h"
36#import "CCTextureCache.h"
37#import "Support/CGPointExtension.h"
38
39#pragma mark -
40#pragma mark CCSpriteBatchNode Extension
41
42@interface CCSpriteBatchNode (TMXTiledMapExtensions)
43-(id) addSpriteWithoutQuad:(CCSprite*)child z:(NSUInteger)z tag:(NSInteger)aTag;
44-(void) addQuadFromSprite:(CCSprite*)sprite quadIndex:(NSUInteger)index;
45@end
46
47/* IMPORTANT XXX IMPORTNAT:
48 * These 2 methods can't be part of CCTMXLayer since they call [super add...], and CCSpriteBatchNode#add SHALL not be called
49 */
50@implementation CCSpriteBatchNode (TMXTiledMapExtension)
51
52/* Adds a quad into the texture atlas but it won't be added into the children array.
53 This method should be called only when you are dealing with very big AtlasSrite and when most of the CCSprite won't be updated.
54 For example: a tile map (CCTMXMap) or a label with lots of characgers (CCLabelBMFont)
55 */
56-(void) addQuadFromSprite:(CCSprite*)sprite quadIndex:(NSUInteger)index
57{
58 NSAssert( sprite != nil, @"Argument must be non-nil");
59 NSAssert( [sprite isKindOfClass:[CCSprite class]], @"CCSpriteBatchNode only supports CCSprites as children");
60
61
62 while(index >= textureAtlas_.capacity || textureAtlas_.capacity == textureAtlas_.totalQuads )
63 [self increaseAtlasCapacity];
64
65 //
66 // update the quad directly. Don't add the sprite to the scene graph
67 //
68
69 [sprite useBatchNode:self];
70 [sprite setAtlasIndex:index];
71
72 ccV3F_C4B_T2F_Quad quad = [sprite quad];
73 [textureAtlas_ insertQuad:&quad atIndex:index];
74
75 // XXX: updateTransform will update the textureAtlas too using updateQuad.
76 // XXX: so, it should be AFTER the insertQuad
77 [sprite setDirty:YES];
78 [sprite updateTransform];
79}
80
81/* This is the opposite of "addQuadFromSprite.
82 It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas
83 */
84-(id) addSpriteWithoutQuad:(CCSprite*)child z:(NSUInteger)z tag:(NSInteger)aTag
85{
86 NSAssert( child != nil, @"Argument must be non-nil");
87 NSAssert( [child isKindOfClass:[CCSprite class]], @"CCSpriteBatchNode only supports CCSprites as children");
88
89 // quad index is Z
90 [child setAtlasIndex:z];
91
92 // XXX: optimize with a binary search
93 int i=0;
94 for( CCSprite *c in descendants_ ) {
95 if( c.atlasIndex >= z )
96 break;
97 i++;
98 }
99 [descendants_ insertObject:child atIndex:i];
100
101
102 // IMPORTANT: Call super, and not self. Avoid adding it to the texture atlas array
103 [super addChild:child z:z tag:aTag];
104 return self;
105}
106@end
107
108
109#pragma mark -
110#pragma mark CCTMXLayer
111
112int compareInts (const void * a, const void * b);
113
114
115@interface CCTMXLayer ()
116-(CGPoint) positionForIsoAt:(CGPoint)pos;
117-(CGPoint) positionForOrthoAt:(CGPoint)pos;
118-(CGPoint) positionForHexAt:(CGPoint)pos;
119
120-(CGPoint) calculateLayerOffset:(CGPoint)offset;
121
122/* optimization methos */
123-(CCSprite*) appendTileForGID:(uint32_t)gid at:(CGPoint)pos;
124-(CCSprite*) insertTileForGID:(uint32_t)gid at:(CGPoint)pos;
125-(CCSprite*) updateTileForGID:(uint32_t)gid at:(CGPoint)pos;
126
127/* The layer recognizes some special properties, like cc_vertez */
128-(void) parseInternalProperties;
129
130-(NSInteger) vertexZForPos:(CGPoint)pos;
131
132// index
133-(NSUInteger) atlasIndexForExistantZ:(NSUInteger)z;
134-(NSUInteger) atlasIndexForNewZ:(NSUInteger)z;
135@end
136
137@implementation CCTMXLayer
138@synthesize layerSize = layerSize_, layerName = layerName_, tiles = tiles_;
139@synthesize tileset = tileset_;
140@synthesize layerOrientation = layerOrientation_;
141@synthesize mapTileSize = mapTileSize_;
142@synthesize properties = properties_;
143
144#pragma mark CCTMXLayer - init & alloc & dealloc
145
146+(id) layerWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo
147{
148 return [[[self alloc] initWithTilesetInfo:tilesetInfo layerInfo:layerInfo mapInfo:mapInfo] autorelease];
149}
150
151-(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo
152{
153 // XXX: is 35% a good estimate ?
154 CGSize size = layerInfo.layerSize;
155 float totalNumberOfTiles = size.width * size.height;
156 float capacity = totalNumberOfTiles * 0.35f + 1; // 35 percent is occupied ?
157
158 CCTexture2D *tex = nil;
159 if( tilesetInfo )
160 tex = [[CCTextureCache sharedTextureCache] addImage:tilesetInfo.sourceImage];
161
162 if((self = [super initWithTexture:tex capacity:capacity])) {
163
164 // layerInfo
165 self.layerName = layerInfo.name;
166 layerSize_ = layerInfo.layerSize;
167 tiles_ = layerInfo.tiles;
168 minGID_ = layerInfo.minGID;
169 maxGID_ = layerInfo.maxGID;
170 opacity_ = layerInfo.opacity;
171 self.properties = [NSMutableDictionary dictionaryWithDictionary:layerInfo.properties];
172
173 // tilesetInfo
174 self.tileset = tilesetInfo;
175
176 // mapInfo
177 mapTileSize_ = mapInfo.tileSize;
178 layerOrientation_ = mapInfo.orientation;
179
180 // offset (after layer orientation is set);
181 CGPoint offset = [self calculateLayerOffset:layerInfo.offset];
182 [self setPositionInPixels:offset];
183
184 atlasIndexArray_ = ccCArrayNew(totalNumberOfTiles);
185
186 [self setContentSizeInPixels: CGSizeMake( layerSize_.width * mapTileSize_.width, layerSize_.height * mapTileSize_.height )];
187
188 useAutomaticVertexZ_= NO;
189 vertexZvalue_ = 0;
190 alphaFuncValue_ = 0;
191
192 }
193 return self;
194}
195
196- (void) dealloc
197{
198 [layerName_ release];
199 [tileset_ release];
200 [reusedTile_ release];
201 [properties_ release];
202
203 if( atlasIndexArray_ ) {
204 ccCArrayFree(atlasIndexArray_);
205 atlasIndexArray_ = NULL;
206 }
207
208 if( tiles_ ) {
209 free(tiles_);
210 tiles_ = NULL;
211 }
212
213 [super dealloc];
214}
215
216-(void) releaseMap
217{
218 if( tiles_) {
219 free( tiles_);
220 tiles_ = NULL;
221 }
222
223 if( atlasIndexArray_ ) {
224 ccCArrayFree(atlasIndexArray_);
225 atlasIndexArray_ = NULL;
226 }
227}
228
229#pragma mark CCTMXLayer - setup Tiles
230
231-(void) setupTiles
232{
233 // Optimization: quick hack that sets the image size on the tileset
234 tileset_.imageSize = [textureAtlas_.texture contentSizeInPixels];
235
236 // By default all the tiles are aliased
237 // pros:
238 // - easier to render
239 // cons:
240 // - difficult to scale / rotate / etc.
241 [textureAtlas_.texture setAliasTexParameters];
242
243 CFByteOrder o = CFByteOrderGetCurrent();
244
245 // Parse cocos2d properties
246 [self parseInternalProperties];
247
248 for( NSUInteger y=0; y < layerSize_.height; y++ ) {
249 for( NSUInteger x=0; x < layerSize_.width; x++ ) {
250
251 NSUInteger pos = x + layerSize_.width * y;
252 uint32_t gid = tiles_[ pos ];
253
254 // gid are stored in little endian.
255 // if host is big endian, then swap
256 if( o == CFByteOrderBigEndian )
257 gid = CFSwapInt32( gid );
258
259 // XXX: gid == 0 --> empty tile
260 if( gid != 0 ) {
261 [self appendTileForGID:gid at:ccp(x,y)];
262
263 // Optimization: update min and max GID rendered by the layer
264 minGID_ = MIN(gid, minGID_);
265 maxGID_ = MAX(gid, maxGID_);
266 }
267 }
268 }
269
270 NSAssert( maxGID_ >= tileset_.firstGid &&
271 minGID_ >= tileset_.firstGid, @"TMX: Only 1 tilset per layer is supported");
272}
273
274#pragma mark CCTMXLayer - Properties
275
276-(id) propertyNamed:(NSString *)propertyName
277{
278 return [properties_ valueForKey:propertyName];
279}
280
281-(void) parseInternalProperties
282{
283 // if cc_vertex=automatic, then tiles will be rendered using vertexz
284
285 NSString *vertexz = [self propertyNamed:@"cc_vertexz"];
286 if( vertexz ) {
287 if( [vertexz isEqualToString:@"automatic"] )
288 useAutomaticVertexZ_ = YES;
289 else
290 vertexZvalue_ = [vertexz intValue];
291 }
292
293 NSString *alphaFuncVal = [self propertyNamed:@"cc_alpha_func"];
294 alphaFuncValue_ = [alphaFuncVal floatValue];
295}
296
297#pragma mark CCTMXLayer - obtaining tiles/gids
298
299-(CCSprite*) tileAt:(CGPoint)pos
300{
301 NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position");
302 NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released");
303
304 CCSprite *tile = nil;
305 uint32_t gid = [self tileGIDAt:pos];
306
307 // if GID == 0, then no tile is present
308 if( gid ) {
309 int z = pos.x + pos.y * layerSize_.width;
310 tile = (CCSprite*) [self getChildByTag:z];
311
312 // tile not created yet. create it
313 if( ! tile ) {
314 CGRect rect = [tileset_ rectForGID:gid];
315 tile = [[CCSprite alloc] initWithBatchNode:self rectInPixels:rect];
316 [tile setPositionInPixels: [self positionAt:pos]];
317 [tile setVertexZ: [self vertexZForPos:pos]];
318 tile.anchorPoint = CGPointZero;
319 [tile setOpacity:opacity_];
320
321 NSUInteger indexForZ = [self atlasIndexForExistantZ:z];
322 [self addSpriteWithoutQuad:tile z:indexForZ tag:z];
323 [tile release];
324 }
325 }
326 return tile;
327}
328
329-(uint32_t) tileGIDAt:(CGPoint)pos
330{
331 NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position");
332 NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released");
333
334 NSInteger idx = pos.x + pos.y * layerSize_.width;
335 return tiles_[ idx ];
336}
337
338#pragma mark CCTMXLayer - adding helper methods
339
340-(CCSprite*) insertTileForGID:(uint32_t)gid at:(CGPoint)pos
341{
342 CGRect rect = [tileset_ rectForGID:gid];
343
344 NSInteger z = pos.x + pos.y * layerSize_.width;
345
346 if( ! reusedTile_ )
347 reusedTile_ = [[CCSprite alloc] initWithBatchNode:self rectInPixels:rect];
348 else
349 [reusedTile_ initWithBatchNode:self rectInPixels:rect];
350
351 [reusedTile_ setPositionInPixels: [self positionAt:pos]];
352 [reusedTile_ setVertexZ: [self vertexZForPos:pos]];
353 reusedTile_.anchorPoint = CGPointZero;
354 [reusedTile_ setOpacity:opacity_];
355
356 // get atlas index
357 NSUInteger indexForZ = [self atlasIndexForNewZ:z];
358
359 // Optimization: add the quad without adding a child
360 [self addQuadFromSprite:reusedTile_ quadIndex:indexForZ];
361
362 // insert it into the local atlasindex array
363 ccCArrayInsertValueAtIndex(atlasIndexArray_, (void*)z, indexForZ);
364
365 // update possible children
366 CCSprite *sprite;
367 CCARRAY_FOREACH(children_, sprite) {
368 NSUInteger ai = [sprite atlasIndex];
369 if( ai >= indexForZ)
370 [sprite setAtlasIndex: ai+1];
371 }
372
373 tiles_[z] = gid;
374
375 return reusedTile_;
376}
377
378-(CCSprite*) updateTileForGID:(uint32_t)gid at:(CGPoint)pos
379{
380 CGRect rect = [tileset_ rectForGID:gid];
381
382 int z = pos.x + pos.y * layerSize_.width;
383
384 if( ! reusedTile_ )
385 reusedTile_ = [[CCSprite alloc] initWithBatchNode:self rectInPixels:rect];
386 else
387 [reusedTile_ initWithBatchNode:self rectInPixels:rect];
388
389 [reusedTile_ setPositionInPixels: [self positionAt:pos]];
390 [reusedTile_ setVertexZ: [self vertexZForPos:pos]];
391 reusedTile_.anchorPoint = CGPointZero;
392 [reusedTile_ setOpacity:opacity_];
393
394 // get atlas index
395 NSUInteger indexForZ = [self atlasIndexForExistantZ:z];
396
397 [reusedTile_ setAtlasIndex:indexForZ];
398 [reusedTile_ setDirty:YES];
399 [reusedTile_ updateTransform];
400 tiles_[z] = gid;
401
402 return reusedTile_;
403}
404
405
406// used only when parsing the map. useless after the map was parsed
407// since lot's of assumptions are no longer true
408-(CCSprite*) appendTileForGID:(uint32_t)gid at:(CGPoint)pos
409{
410 CGRect rect = [tileset_ rectForGID:gid];
411
412 NSInteger z = pos.x + pos.y * layerSize_.width;
413
414 if( ! reusedTile_ )
415 reusedTile_ = [[CCSprite alloc] initWithBatchNode:self rectInPixels:rect];
416 else
417 [reusedTile_ initWithBatchNode:self rectInPixels:rect];
418
419 [reusedTile_ setPositionInPixels: [self positionAt:pos]];
420 [reusedTile_ setVertexZ: [self vertexZForPos:pos]];
421 reusedTile_.anchorPoint = CGPointZero;
422 [reusedTile_ setOpacity:opacity_];
423
424 // optimization:
425 // The difference between appendTileForGID and insertTileforGID is that append is faster, since
426 // it appends the tile at the end of the texture atlas
427 NSUInteger indexForZ = atlasIndexArray_->num;
428
429
430 // don't add it using the "standard" way.
431 [self addQuadFromSprite:reusedTile_ quadIndex:indexForZ];
432
433
434 // append should be after addQuadFromSprite since it modifies the quantity values
435 ccCArrayInsertValueAtIndex(atlasIndexArray_, (void*)z, indexForZ);
436
437 return reusedTile_;
438}
439
440#pragma mark CCTMXLayer - atlasIndex and Z
441
442int compareInts (const void * a, const void * b)
443{
444 return ( *(int*)a - *(int*)b );
445}
446
447-(NSUInteger) atlasIndexForExistantZ:(NSUInteger)z
448{
449 NSInteger key = z;
450 NSInteger *item = bsearch((void*)&key, (void*)&atlasIndexArray_->arr[0], atlasIndexArray_->num, sizeof(void*), compareInts);
451
452 NSAssert( item, @"TMX atlas index not found. Shall not happen");
453
454 NSUInteger index = ((NSInteger)item - (NSInteger)atlasIndexArray_->arr) / sizeof(void*);
455 return index;
456}
457
458-(NSUInteger)atlasIndexForNewZ:(NSUInteger)z
459{
460 // XXX: This can be improved with a sort of binary search
461 NSUInteger i = 0;
462 for(i = 0; i< atlasIndexArray_->num; i++) {
463 NSUInteger val = (NSUInteger) atlasIndexArray_->arr[i];
464 if( z < val )
465 break;
466 }
467 return i;
468}
469
470#pragma mark CCTMXLayer - adding / remove tiles
471
472-(void) setTileGID:(uint32_t)gid at:(CGPoint)pos
473{
474 NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position");
475 NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released");
476 NSAssert( gid == 0 || gid >= tileset_.firstGid, @"TMXLayer: invalid gid" );
477
478 uint32_t currentGID = [self tileGIDAt:pos];
479
480 if( currentGID != gid ) {
481
482 // setting gid=0 is equal to remove the tile
483 if( gid == 0 )
484 [self removeTileAt:pos];
485
486 // empty tile. create a new one
487 else if( currentGID == 0 )
488 [self insertTileForGID:gid at:pos];
489
490 // modifying an existing tile with a non-empty tile
491 else {
492
493 NSUInteger z = pos.x + pos.y * layerSize_.width;
494 id sprite = [self getChildByTag:z];
495 if( sprite ) {
496 CGRect rect = [tileset_ rectForGID:gid];
497 [sprite setTextureRectInPixels:rect rotated:NO untrimmedSize:rect.size];
498 tiles_[z] = gid;
499 } else
500 [self updateTileForGID:gid at:pos];
501 }
502 }
503}
504
505-(void) addChild: (CCNode*)node z:(NSInteger)z tag:(NSInteger)tag
506{
507 NSAssert(NO, @"addChild: is not supported on CCTMXLayer. Instead use setTileGID:at:/tileAt:");
508}
509
510-(void) removeChild:(CCSprite*)sprite cleanup:(BOOL)cleanup
511{
512 // allows removing nil objects
513 if( ! sprite )
514 return;
515
516 NSAssert( [children_ containsObject:sprite], @"Tile does not belong to TMXLayer");
517
518 NSUInteger atlasIndex = [sprite atlasIndex];
519 NSUInteger zz = (NSUInteger) atlasIndexArray_->arr[atlasIndex];
520 tiles_[zz] = 0;
521 ccCArrayRemoveValueAtIndex(atlasIndexArray_, atlasIndex);
522 [super removeChild:sprite cleanup:cleanup];
523}
524
525-(void) removeTileAt:(CGPoint)pos
526{
527 NSAssert( pos.x < layerSize_.width && pos.y < layerSize_.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position");
528 NSAssert( tiles_ && atlasIndexArray_, @"TMXLayer: the tiles map has been released");
529
530 uint32_t gid = [self tileGIDAt:pos];
531
532 if( gid ) {
533
534 NSUInteger z = pos.x + pos.y * layerSize_.width;
535 NSUInteger atlasIndex = [self atlasIndexForExistantZ:z];
536
537 // remove tile from GID map
538 tiles_[z] = 0;
539
540 // remove tile from atlas position array
541 ccCArrayRemoveValueAtIndex(atlasIndexArray_, atlasIndex);
542
543 // remove it from sprites and/or texture atlas
544 id sprite = [self getChildByTag:z];
545 if( sprite )
546 [super removeChild:sprite cleanup:YES];
547 else {
548 [textureAtlas_ removeQuadAtIndex:atlasIndex];
549
550 // update possible children
551 CCARRAY_FOREACH(children_, sprite) {
552 NSUInteger ai = [sprite atlasIndex];
553 if( ai >= atlasIndex) {
554 [sprite setAtlasIndex: ai-1];
555 }
556 }
557 }
558 }
559}
560
561#pragma mark CCTMXLayer - obtaining positions, offset
562
563-(CGPoint) calculateLayerOffset:(CGPoint)pos
564{
565 CGPoint ret = CGPointZero;
566 switch( layerOrientation_ ) {
567 case CCTMXOrientationOrtho:
568 ret = ccp( pos.x * mapTileSize_.width, -pos.y *mapTileSize_.height);
569 break;
570 case CCTMXOrientationIso:
571 ret = ccp( (mapTileSize_.width /2) * (pos.x - pos.y),
572 (mapTileSize_.height /2 ) * (-pos.x - pos.y) );
573 break;
574 case CCTMXOrientationHex:
575 NSAssert(CGPointEqualToPoint(pos, CGPointZero), @"offset for hexagonal map not implemented yet");
576 break;
577 }
578 return ret;
579}
580
581-(CGPoint) positionAt:(CGPoint)pos
582{
583 CGPoint ret = CGPointZero;
584 switch( layerOrientation_ ) {
585 case CCTMXOrientationOrtho:
586 ret = [self positionForOrthoAt:pos];
587 break;
588 case CCTMXOrientationIso:
589 ret = [self positionForIsoAt:pos];
590 break;
591 case CCTMXOrientationHex:
592 ret = [self positionForHexAt:pos];
593 break;
594 }
595 return ret;
596}
597
598-(CGPoint) positionForOrthoAt:(CGPoint)pos
599{
600 CGPoint xy = {
601 pos.x * mapTileSize_.width,
602 (layerSize_.height - pos.y - 1) * mapTileSize_.height,
603 };
604 return xy;
605}
606
607-(CGPoint) positionForIsoAt:(CGPoint)pos
608{
609 CGPoint xy = {
610 mapTileSize_.width /2 * ( layerSize_.width + pos.x - pos.y - 1),
611 mapTileSize_.height /2 * (( layerSize_.height * 2 - pos.x - pos.y) - 2),
612 };
613 return xy;
614}
615
616-(CGPoint) positionForHexAt:(CGPoint)pos
617{
618 float diffY = 0;
619 if( (int)pos.x % 2 == 1 )
620 diffY = -mapTileSize_.height/2 ;
621
622 CGPoint xy = {
623 pos.x * mapTileSize_.width*3/4,
624 (layerSize_.height - pos.y - 1) * mapTileSize_.height + diffY
625 };
626 return xy;
627}
628
629-(NSInteger) vertexZForPos:(CGPoint)pos
630{
631 NSInteger ret = 0;
632 NSUInteger maxVal = 0;
633 if( useAutomaticVertexZ_ ) {
634 switch( layerOrientation_ ) {
635 case CCTMXOrientationIso:
636 maxVal = layerSize_.width + layerSize_.height;
637 ret = -(maxVal - (pos.x + pos.y));
638 break;
639 case CCTMXOrientationOrtho:
640 ret = -(layerSize_.height-pos.y);
641 break;
642 case CCTMXOrientationHex:
643 NSAssert(NO,@"TMX Hexa zOrder not supported");
644 break;
645 default:
646 NSAssert(NO,@"TMX invalid value");
647 break;
648 }
649 } else
650 ret = vertexZvalue_;
651
652 return ret;
653}
654
655#pragma mark CCTMXLayer - draw
656
657-(void) draw
658{
659 if( useAutomaticVertexZ_ ) {
660 glEnable(GL_ALPHA_TEST);
661 glAlphaFunc(GL_GREATER, alphaFuncValue_);
662 }
663
664 [super draw];
665
666 if( useAutomaticVertexZ_ )
667 glDisable(GL_ALPHA_TEST);
668}
669@end
670