|
42 | 42 | #import "CCSprite.h"
|
43 | 43 | #import "Support/CCFileUtils.h"
|
44 | 44 | #import "CCTexture.h"
|
45 |
| - |
| 45 | +#import "CCDirector.h" |
46 | 46 |
|
47 | 47 | @interface CCSpriteFrame(Proxy)
|
48 | 48 | - (BOOL)hasProxy;
|
@@ -180,6 +180,43 @@ - (void) registerSpriteFramesFile:(NSString*)plist
|
180 | 180 |
|
181 | 181 | #pragma mark CCSpriteFrameCache - loading sprite frames
|
182 | 182 |
|
| 183 | +-(void) addSpriteFrameWithDictionary:(NSDictionary*)frameDict texture:(CCTexture *)texture scaleSuffix:(NSString *)scaleSuffix |
| 184 | +{ |
| 185 | + // Reducing frame name string to base asset name by cutting of extensions and resolution suffix. |
| 186 | + NSString *frameName = [[frameDict objectForKey:@"name"] stringByDeletingPathExtension]; |
| 187 | + NSString *frameDictKey = frameName; |
| 188 | + |
| 189 | + if (frameName.length > 3) { |
| 190 | + NSString *resolutionComponent = [frameName substringWithRange:NSMakeRange(frameName.length -3, 3)]; |
| 191 | + if ([resolutionComponent isEqualToString:scaleSuffix]) { |
| 192 | + frameDictKey = [frameDictKey stringByReplacingCharactersInRange:NSMakeRange(frameDictKey.length - 3, 3) withString:@""]; |
| 193 | + } |
| 194 | + } |
| 195 | + |
| 196 | + CCSpriteFrame *spriteFrame=nil; |
| 197 | + |
| 198 | + // get values |
| 199 | + CGSize spriteSize = CCRectFromString([frameDict objectForKey:@"textureRect"]).size; |
| 200 | + CGPoint spriteOffset = CCPointFromString([frameDict objectForKey:@"spriteOffset"]); |
| 201 | + CGSize spriteSourceSize = CCSizeFromString([frameDict objectForKey:@"spriteSourceSize"]); |
| 202 | + CGRect textureRect = CCRectFromString([frameDict objectForKey:@"textureRect"]); |
| 203 | + BOOL textureRotated = [[frameDict objectForKey:@"textureRotated"] boolValue]; |
| 204 | + |
| 205 | + // get aliases |
| 206 | + NSArray *aliases = [frameDict objectForKey:@"aliases"]; |
| 207 | + for(NSString *alias in aliases) { |
| 208 | + if( [_spriteFramesAliases objectForKey:alias] ) |
| 209 | + CCLOGWARN(@"cocos2d: WARNING: an alias with name %@ already exists",alias); |
| 210 | + |
| 211 | + [_spriteFramesAliases setObject:frameDictKey forKey:alias]; |
| 212 | + } |
| 213 | + |
| 214 | + // set frame info |
| 215 | + CGRect rectInPixels = CGRectMake(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height); |
| 216 | + |
| 217 | + [self addSpriteFrame:spriteFrame withTextureReference:texture key:frameDictKey rectInPixels:rectInPixels rotated:textureRotated offset:spriteOffset originalSize:spriteSourceSize]; |
| 218 | +} |
| 219 | + |
183 | 220 | -(void) addSpriteFramesWithDictionary:(NSDictionary*)dictionary textureReference:(id)textureReference
|
184 | 221 | {
|
185 | 222 | /*
|
@@ -272,33 +309,38 @@ -(void) addSpriteFramesWithDictionary:(NSDictionary*)dictionary textureReference
|
272 | 309 | frameOffset = spriteOffset;
|
273 | 310 | originalSize = spriteSourceSize;
|
274 | 311 | }
|
275 |
| - |
276 |
| - NSString *textureFileName = nil; |
277 |
| - CCTexture * texture = nil; |
278 |
| - |
279 |
| - if ( [textureReference isKindOfClass:[NSString class]] ) |
280 |
| - { |
281 |
| - textureFileName = textureReference; |
282 |
| - } |
283 |
| - else if ( [textureReference isKindOfClass:[CCTexture class]] ) |
284 |
| - { |
285 |
| - texture = textureReference; |
286 |
| - } |
287 |
| - |
288 |
| - if ( textureFileName ) |
289 |
| - { |
290 |
| - spriteFrame = [[CCSpriteFrame alloc] initWithTextureFilename:textureFileName rectInPixels:rectInPixels rotated:isRotated offset:frameOffset originalSize:originalSize]; |
291 |
| - } |
292 |
| - else |
293 |
| - { |
294 |
| - spriteFrame = [[CCSpriteFrame alloc] initWithTexture:texture rectInPixels:rectInPixels rotated:isRotated offset:frameOffset originalSize:originalSize]; |
295 |
| - } |
296 |
| - |
297 |
| - // add sprite frame |
298 |
| - [_spriteFrames setObject:spriteFrame forKey:frameDictKey]; |
| 312 | + |
| 313 | + [self addSpriteFrame:spriteFrame withTextureReference:textureReference key:frameDictKey rectInPixels:rectInPixels rotated:isRotated offset:frameOffset originalSize:originalSize]; |
299 | 314 | }
|
300 | 315 | }
|
301 | 316 |
|
| 317 | +- (void)addSpriteFrame:(CCSpriteFrame *)spriteFrame withTextureReference:(id)textureReference key:(NSString *)key rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize |
| 318 | +{ |
| 319 | + NSString *textureFileName = nil; |
| 320 | + CCTexture * texture = nil; |
| 321 | + |
| 322 | + if ( [textureReference isKindOfClass:[NSString class]] ) |
| 323 | + { |
| 324 | + textureFileName = textureReference; |
| 325 | + } |
| 326 | + else if ( [textureReference isKindOfClass:[CCTexture class]] ) |
| 327 | + { |
| 328 | + texture = textureReference; |
| 329 | + } |
| 330 | + |
| 331 | + if ( textureFileName ) |
| 332 | + { |
| 333 | + spriteFrame = [[CCSpriteFrame alloc] initWithTextureFilename:textureFileName rectInPixels:rect rotated:rotated offset:offset originalSize:originalSize]; |
| 334 | + } |
| 335 | + else |
| 336 | + { |
| 337 | + spriteFrame = [[CCSpriteFrame alloc] initWithTexture:texture rectInPixels:rect rotated:rotated offset:offset originalSize:originalSize]; |
| 338 | + } |
| 339 | + |
| 340 | + // add sprite frame |
| 341 | + [_spriteFrames setObject:spriteFrame forKey:key]; |
| 342 | +} |
| 343 | + |
302 | 344 | -(void) addSpriteFramesWithDictionary:(NSDictionary*)dictionary textureFilename:(NSString*)textureFilename
|
303 | 345 | {
|
304 | 346 | return [self addSpriteFramesWithDictionary:dictionary textureReference:textureFilename];
|
@@ -376,6 +418,93 @@ -(void) addSpriteFramesWithFile:(NSString*)plist
|
376 | 418 |
|
377 | 419 | }
|
378 | 420 |
|
| 421 | +-(void) addSpriteFramesFromSpriteAtlasAssetNamed:(NSString *)atlasAssetName |
| 422 | +{ |
| 423 | + NSDictionary *dictionary = [self dictionaryForSpriteAtlasAssetNamed:atlasAssetName]; |
| 424 | + if (!dictionary) { |
| 425 | + CCLOG(@"cocos2d: CCSpriteFrameCache: No sprite atlas asset found with name: %@", atlasAssetName); |
| 426 | + return; |
| 427 | + } |
| 428 | + if (dictionary != nil) { |
| 429 | + NSInteger version = [[dictionary objectForKey:@"version"] integerValue]; |
| 430 | + if (version != 1) { |
| 431 | + CCLOG(@"cocos2d: WARNING: Unsupported version of sprite atlas asset file version: %ld filename: %@", (long)version, atlasAssetName); |
| 432 | + return; |
| 433 | + } |
| 434 | + |
| 435 | + NSAssert([[dictionary objectForKey:@"format"] isEqualToString:@"APPL"], @"format is not supported for CCSpriteFrameCache addSpriteFramesFromSpriteAtlasAssetNamed:textureFilename:"); |
| 436 | + |
| 437 | + int scale = [[CCDirector sharedDirector] contentScaleFactor]; |
| 438 | + NSString *scaleSuffix = scale == 1 ? @"" : [NSString stringWithFormat:@"@%dx",scale]; |
| 439 | + |
| 440 | + NSArray <NSDictionary *>*imageDicts = [dictionary objectForKey:@"images"]; |
| 441 | + NSArray *imagePaths = [imageDicts valueForKeyPath:@"path"]; |
| 442 | + |
| 443 | + // Trying to find image paths for the current devices native resolution. |
| 444 | + NSMutableIndexSet *indexes = [self indexesForImagePaths:imagePaths forFilename:atlasAssetName withSuffix:scaleSuffix].mutableCopy; |
| 445 | + |
| 446 | + if (indexes.count == 0) { |
| 447 | + // Falling back to using @1x graphics if the expected resolution is not found. |
| 448 | + [indexes addIndexes:[self indexesForImagePaths:imagePaths forFilename:atlasAssetName withSuffix:nil]]; |
| 449 | + scaleSuffix = nil; |
| 450 | + } |
| 451 | + |
| 452 | + // Only processing the image dictionaries that are using textures with the correct resolution. |
| 453 | + for (NSDictionary *imageDict in [imageDicts objectsAtIndexes:indexes]) { |
| 454 | + NSArray *spriteFrames = [imageDict objectForKey:@"subimages"]; |
| 455 | + NSString *resourceName = [imageDict objectForKey:@"path"]; |
| 456 | + NSString *resourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:[NSString stringWithFormat:@"/%@.atlasc/%@",atlasAssetName,resourceName]]; |
| 457 | + if ([[NSFileManager defaultManager] fileExistsAtPath:resourcePath]) { |
| 458 | + // Loading the sprite atlas image from the file system |
| 459 | + NSData *imageData = [NSData dataWithContentsOfFile:resourcePath]; |
| 460 | + CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData( (__bridge CFDataRef) imageData); |
| 461 | + CGImageRef imageRef = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); |
| 462 | + |
| 463 | + // Scale suffix will be an empty string if there wasn't any native resolution graphics in the sprite atlas. |
| 464 | + // In that case the @1x graphics is loaded as fallback. |
| 465 | + CCTexture *texture = [[CCTexture alloc] initWithCGImage:imageRef contentScale:scaleSuffix.length > 0 ? [[CCDirector sharedDirector] contentScaleFactor] : 1.0]; |
| 466 | + |
| 467 | + CGDataProviderRelease(imgDataProvider); |
| 468 | + CGImageRelease(imageRef); |
| 469 | + |
| 470 | + // Loading the frames and connecting them with the texture. |
| 471 | + for (NSDictionary *frameDict in spriteFrames) { |
| 472 | + [self addSpriteFrameWithDictionary:frameDict texture:texture scaleSuffix:scaleSuffix]; |
| 473 | + } |
| 474 | + } else { |
| 475 | + CCLOG(@"cocos2d: WARNING: image not found at file path: %@",resourcePath); |
| 476 | + } |
| 477 | + } |
| 478 | + } |
| 479 | +} |
| 480 | + |
| 481 | +- (NSDictionary *) dictionaryForSpriteAtlasAssetNamed:(NSString *)assetName |
| 482 | +{ |
| 483 | + // Looking for the file in resource root |
| 484 | + NSString *resourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:[NSString stringWithFormat:@"/%1$@.atlasc/%1$@.plist",assetName]]; |
| 485 | + if ([[NSFileManager defaultManager] fileExistsAtPath:resourcePath]) { |
| 486 | + NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:resourcePath]; |
| 487 | + |
| 488 | + return dict; |
| 489 | + } |
| 490 | + return nil; |
| 491 | +} |
| 492 | + |
| 493 | +- (NSIndexSet *)indexesForImagePaths:(NSArray *)imagePaths forFilename:(NSString *)filename withSuffix:(NSString *)scaleSuffix |
| 494 | +{ |
| 495 | + // Checking for indexes that has image paths with the provided suffix. |
| 496 | + NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init]; |
| 497 | + for (NSString * searchString in imagePaths) { |
| 498 | + NSString *strippedString = [searchString stringByDeletingPathExtension]; |
| 499 | + strippedString = [strippedString stringByReplacingOccurrencesOfString:filename withString:@""]; |
| 500 | + strippedString = [strippedString stringByReplacingCharactersInRange:NSMakeRange(0, 2) withString:@""]; |
| 501 | + if ([strippedString isEqualToString:scaleSuffix]) { |
| 502 | + [indexes addIndex:[imagePaths indexOfObject:searchString]]; |
| 503 | + } |
| 504 | + } |
| 505 | + return indexes; |
| 506 | +} |
| 507 | + |
379 | 508 | -(void) addSpriteFrame:(CCSpriteFrame*)frame name:(NSString*)frameName
|
380 | 509 | {
|
381 | 510 | [_spriteFrames setObject:frame forKey:frameName];
|
|
0 commit comments