summary refs log tree commit diff stats
path: root/libs/cocos2d/CCSpriteFrameCache.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocos2d/CCSpriteFrameCache.m')
-rwxr-xr-xlibs/cocos2d/CCSpriteFrameCache.m347
1 files changed, 347 insertions, 0 deletions
diff --git a/libs/cocos2d/CCSpriteFrameCache.m b/libs/cocos2d/CCSpriteFrameCache.m new file mode 100755 index 0000000..f154c3d --- /dev/null +++ b/libs/cocos2d/CCSpriteFrameCache.m
@@ -0,0 +1,347 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2009 Jason Booth
5 *
6 * Copyright (c) 2009 Robert J Payne
7 *
8 * Copyright (c) 2008-2010 Ricardo Quesada
9 * Copyright (c) 2011 Zynga Inc.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 */
30
31/*
32 * To create sprite frames and texture atlas, use this tool:
33 * http://zwoptex.zwopple.com/
34 */
35
36#import "Platforms/CCNS.h"
37#import "ccMacros.h"
38#import "CCTextureCache.h"
39#import "CCSpriteFrameCache.h"
40#import "CCSpriteFrame.h"
41#import "CCSprite.h"
42#import "Support/CCFileUtils.h"
43
44
45@implementation CCSpriteFrameCache
46
47#pragma mark CCSpriteFrameCache - Alloc, Init & Dealloc
48
49static CCSpriteFrameCache *sharedSpriteFrameCache_=nil;
50
51+ (CCSpriteFrameCache *)sharedSpriteFrameCache
52{
53 if (!sharedSpriteFrameCache_)
54 sharedSpriteFrameCache_ = [[CCSpriteFrameCache alloc] init];
55
56 return sharedSpriteFrameCache_;
57}
58
59+(id)alloc
60{
61 NSAssert(sharedSpriteFrameCache_ == nil, @"Attempted to allocate a second instance of a singleton.");
62 return [super alloc];
63}
64
65+(void)purgeSharedSpriteFrameCache
66{
67 [sharedSpriteFrameCache_ release];
68 sharedSpriteFrameCache_ = nil;
69}
70
71-(id) init
72{
73 if( (self=[super init]) ) {
74 spriteFrames_ = [[NSMutableDictionary alloc] initWithCapacity: 100];
75 spriteFramesAliases_ = [[NSMutableDictionary alloc] initWithCapacity:10];
76 }
77
78 return self;
79}
80
81- (NSString*) description
82{
83 return [NSString stringWithFormat:@"<%@ = %08X | num of sprite frames = %i>", [self class], self, [spriteFrames_ count]];
84}
85
86-(void) dealloc
87{
88 CCLOGINFO(@"cocos2d: deallocing %@", self);
89
90 [spriteFrames_ release];
91 [spriteFramesAliases_ release];
92 [super dealloc];
93}
94
95#pragma mark CCSpriteFrameCache - loading sprite frames
96
97-(void) addSpriteFramesWithDictionary:(NSDictionary*)dictionary texture:(CCTexture2D*)texture
98{
99 /*
100 Supported Zwoptex Formats:
101 ZWTCoordinatesFormatOptionXMLLegacy = 0, // Flash Version
102 ZWTCoordinatesFormatOptionXML1_0 = 1, // Desktop Version 0.0 - 0.4b
103 ZWTCoordinatesFormatOptionXML1_1 = 2, // Desktop Version 1.0.0 - 1.0.1
104 ZWTCoordinatesFormatOptionXML1_2 = 3, // Desktop Version 1.0.2+
105 */
106 NSDictionary *metadataDict = [dictionary objectForKey:@"metadata"];
107 NSDictionary *framesDict = [dictionary objectForKey:@"frames"];
108
109 int format = 0;
110
111 // get the format
112 if(metadataDict != nil)
113 format = [[metadataDict objectForKey:@"format"] intValue];
114
115 // check the format
116 NSAssert( format >= 0 && format <= 3, @"cocos2d: WARNING: format is not supported for CCSpriteFrameCache addSpriteFramesWithDictionary:texture:");
117
118
119 // add real frames
120 for(NSString *frameDictKey in framesDict) {
121 NSDictionary *frameDict = [framesDict objectForKey:frameDictKey];
122 CCSpriteFrame *spriteFrame;
123 if(format == 0) {
124 float x = [[frameDict objectForKey:@"x"] floatValue];
125 float y = [[frameDict objectForKey:@"y"] floatValue];
126 float w = [[frameDict objectForKey:@"width"] floatValue];
127 float h = [[frameDict objectForKey:@"height"] floatValue];
128 float ox = [[frameDict objectForKey:@"offsetX"] floatValue];
129 float oy = [[frameDict objectForKey:@"offsetY"] floatValue];
130 int ow = [[frameDict objectForKey:@"originalWidth"] intValue];
131 int oh = [[frameDict objectForKey:@"originalHeight"] intValue];
132 // check ow/oh
133 if(!ow || !oh)
134 CCLOG(@"cocos2d: WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenerate the .plist");
135
136 // abs ow/oh
137 ow = abs(ow);
138 oh = abs(oh);
139 // create frame
140
141 spriteFrame = [[CCSpriteFrame alloc] initWithTexture:texture
142 rectInPixels:CGRectMake(x, y, w, h)
143 rotated:NO
144 offset:CGPointMake(ox, oy)
145 originalSize:CGSizeMake(ow, oh)];
146 } else if(format == 1 || format == 2) {
147 CGRect frame = CCRectFromString([frameDict objectForKey:@"frame"]);
148 BOOL rotated = NO;
149
150 // rotation
151 if(format == 2)
152 rotated = [[frameDict objectForKey:@"rotated"] boolValue];
153
154 CGPoint offset = CCPointFromString([frameDict objectForKey:@"offset"]);
155 CGSize sourceSize = CCSizeFromString([frameDict objectForKey:@"sourceSize"]);
156
157 // create frame
158 spriteFrame = [[CCSpriteFrame alloc] initWithTexture:texture
159 rectInPixels:frame
160 rotated:rotated
161 offset:offset
162 originalSize:sourceSize];
163 } else if(format == 3) {
164 // get values
165 CGSize spriteSize = CCSizeFromString([frameDict objectForKey:@"spriteSize"]);
166 CGPoint spriteOffset = CCPointFromString([frameDict objectForKey:@"spriteOffset"]);
167 CGSize spriteSourceSize = CCSizeFromString([frameDict objectForKey:@"spriteSourceSize"]);
168 CGRect textureRect = CCRectFromString([frameDict objectForKey:@"textureRect"]);
169 BOOL textureRotated = [[frameDict objectForKey:@"textureRotated"] boolValue];
170
171 // get aliases
172 NSArray *aliases = [frameDict objectForKey:@"aliases"];
173 for(NSString *alias in aliases) {
174 if( [spriteFramesAliases_ objectForKey:alias] )
175 CCLOG(@"cocos2d: WARNING: an alias with name %@ already exists",alias);
176
177 [spriteFramesAliases_ setObject:frameDictKey forKey:alias];
178 }
179
180 // create frame
181 spriteFrame = [[CCSpriteFrame alloc] initWithTexture:texture
182 rectInPixels:CGRectMake(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height)
183 rotated:textureRotated
184 offset:spriteOffset
185 originalSize:spriteSourceSize];
186 }
187
188 // add sprite frame
189 [spriteFrames_ setObject:spriteFrame forKey:frameDictKey];
190 [spriteFrame release];
191 }
192}
193
194-(void) addSpriteFramesWithFile:(NSString*)plist texture:(CCTexture2D*)texture
195{
196 NSString *path = [CCFileUtils fullPathFromRelativePath:plist];
197 NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
198
199 [self addSpriteFramesWithDictionary:dict texture:texture];
200}
201
202-(void) addSpriteFramesWithFile:(NSString*)plist textureFile:(NSString*)textureFileName
203{
204 NSAssert( textureFileName, @"Invalid texture file name");
205 CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:textureFileName];
206
207 if( texture )
208 [self addSpriteFramesWithFile:plist texture:texture];
209 else
210 CCLOG(@"cocos2d: CCSpriteFrameCache: couldn't load texture file. File not found: %@", textureFileName);
211}
212
213-(void) addSpriteFramesWithFile:(NSString*)plist
214{
215 NSString *path = [CCFileUtils fullPathFromRelativePath:plist];
216 NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
217
218 NSString *texturePath = nil;
219 NSDictionary *metadataDict = [dict objectForKey:@"metadata"];
220 if( metadataDict )
221 // try to read texture file name from meta data
222 texturePath = [metadataDict objectForKey:@"textureFileName"];
223
224
225 if( texturePath )
226 {
227 // build texture path relative to plist file
228 NSString *textureBase = [plist stringByDeletingLastPathComponent];
229 texturePath = [textureBase stringByAppendingPathComponent:texturePath];
230 } else {
231 // build texture path by replacing file extension
232 texturePath = [plist stringByDeletingPathExtension];
233 texturePath = [texturePath stringByAppendingPathExtension:@"png"];
234
235 CCLOG(@"cocos2d: CCSpriteFrameCache: Trying to use file '%@' as texture", texturePath);
236 }
237
238 CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:texturePath];
239
240 if( texture )
241 [self addSpriteFramesWithDictionary:dict texture:texture];
242
243 else
244 CCLOG(@"cocos2d: CCSpriteFrameCache: Couldn't load texture");
245}
246
247-(void) addSpriteFrame:(CCSpriteFrame*)frame name:(NSString*)frameName
248{
249 [spriteFrames_ setObject:frame forKey:frameName];
250}
251
252#pragma mark CCSpriteFrameCache - removing
253
254-(void) removeSpriteFrames
255{
256 [spriteFrames_ removeAllObjects];
257 [spriteFramesAliases_ removeAllObjects];
258}
259
260-(void) removeUnusedSpriteFrames
261{
262 NSArray *keys = [spriteFrames_ allKeys];
263 for( id key in keys ) {
264 id value = [spriteFrames_ objectForKey:key];
265 if( [value retainCount] == 1 ) {
266 CCLOG(@"cocos2d: CCSpriteFrameCache: removing unused frame: %@", key);
267 [spriteFrames_ removeObjectForKey:key];
268 }
269 }
270}
271
272-(void) removeSpriteFrameByName:(NSString*)name
273{
274 // explicit nil handling
275 if( ! name )
276 return;
277
278 // Is this an alias ?
279 NSString *key = [spriteFramesAliases_ objectForKey:name];
280
281 if( key ) {
282 [spriteFrames_ removeObjectForKey:key];
283 [spriteFramesAliases_ removeObjectForKey:name];
284
285 } else
286 [spriteFrames_ removeObjectForKey:name];
287}
288
289- (void) removeSpriteFramesFromFile:(NSString*) plist
290{
291 NSString *path = [CCFileUtils fullPathFromRelativePath:plist];
292 NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
293
294 [self removeSpriteFramesFromDictionary:dict];
295}
296
297- (void) removeSpriteFramesFromDictionary:(NSDictionary*) dictionary
298{
299 NSDictionary *framesDict = [dictionary objectForKey:@"frames"];
300 NSMutableArray *keysToRemove=[NSMutableArray array];
301
302 for(NSString *frameDictKey in framesDict)
303 {
304 if ([spriteFrames_ objectForKey:frameDictKey]!=nil)
305 [keysToRemove addObject:frameDictKey];
306 }
307 [spriteFrames_ removeObjectsForKeys:keysToRemove];
308}
309
310- (void) removeSpriteFramesFromTexture:(CCTexture2D*) texture
311{
312 NSMutableArray *keysToRemove=[NSMutableArray array];
313
314 for (NSString *spriteFrameKey in spriteFrames_)
315 {
316 if ([[spriteFrames_ valueForKey:spriteFrameKey] texture] == texture)
317 [keysToRemove addObject:spriteFrameKey];
318
319 }
320 [spriteFrames_ removeObjectsForKeys:keysToRemove];
321}
322
323#pragma mark CCSpriteFrameCache - getting
324
325-(CCSpriteFrame*) spriteFrameByName:(NSString*)name
326{
327 CCSpriteFrame *frame = [spriteFrames_ objectForKey:name];
328 if( ! frame ) {
329 // try alias dictionary
330 NSString *key = [spriteFramesAliases_ objectForKey:name];
331 frame = [spriteFrames_ objectForKey:key];
332
333 if( ! frame )
334 CCLOG(@"cocos2d: CCSpriteFrameCache: Frame '%@' not found", name);
335 }
336
337 return frame;
338}
339
340#pragma mark CCSpriteFrameCache - sprite creation
341
342-(CCSprite*) createSpriteWithFrameName:(NSString*)name
343{
344 CCSpriteFrame *frame = [spriteFrames_ objectForKey:name];
345 return [CCSprite spriteWithSpriteFrame:frame];
346}
347@end