Пожалуйста, потерпите меня, я собираюсь опубликовать длинный код.
Я делаю подклассы CCSprite:
@interface Character : CCSprite {
}
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect;
@end
@implementation Character
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
NSLog(@"in initWithTexture");
if( (self=[super initWithTexture:texture rect:rect]))
{
}
return self;
}
-(void) dealloc
{
NSLog(@"character dealloced");
[super dealloc];
}
@end
Вопрос № 1: это правильно?
У меня есть слой, содержащий этот спрайт как переменную класса, а также еще один CCSprite.
Character *characterSprite;
CCSprite *burpSprite;
Этот слой также имеет два объекта CCAnimation:
CCAnimation *burpAnim;
CCAnimation *burpParticlesAnim;
В этом классе у меня есть два метода:
- (void) loadBurpAnimation;
- (void) unloadBurpAnimation;
-(void) loadBurpAnimation {
NSString* burpFile;
NSString* burpFilePVR;
NSString* burpParticlesFile;
NSString* burpParticlesFilePVR;
burpFile = @"latestBurp1-1.plist";
burpFilePVR = @"latestBurp1-1.pvr.ccz";
burpParticlesFile = @"burpParticles1-1.plist";
burpParticlesFilePVR = @"burpParticles1-1.png";
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpFile texture:[[CCTextureCache sharedTextureCache] addImage:burpFilePVR]];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpParticlesFile texture:[[CCTextureCache sharedTextureCache] addImage:burpParticlesFilePVR]];
NSMutableArray *burpFrames = [NSMutableArray array];
for(int i = 231; i <= 268; ++i) {
[burpFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"burp.%d.png", i]]];
}
burpAnim = [[CCAnimation alloc] initWithFrames:burpFrames delay:0.04f];
[burpFrames removeAllObjects];
//Burp Particles
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpParticlesFile];
NSMutableArray *burpParticlesFrames = [NSMutableArray array];
for(int i = 3; i <= 37; ++i) {
[burpParticlesFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Burp_%05d.png", i]]];
}
burpParticlesAnim = [[CCAnimation alloc] initWithFrames:burpParticlesFrames delay:0.04f];
[burpParticlesFrames removeAllObjects];
}
-(void) unloadBurpAnimation {
[burpAnim release];
[burpParticlesAnim release];
}
Я должен загрузить анимацию отрыжки в потоке и вызвать метод в главном потоке, чтобы воспроизвести его, который выглядит следующим образом:
-(void) loadAnimation {
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
[dictLock lock];
if( [EAGLContext setCurrentContext:auxEAGLcontext] ) {
[self loadBurpAnimation];
[self performSelectorOnMainThread:@selector(burpAnimation) withObject:nil waitUntilDone:NO];
} else {
CCLOG(@"cocos2d: TetureCache: EAGLContext error");
}
[dictLock unlock];
[autoreleasepool drain];
}
Я знаю, что есть метод для загрузки анимации отдельно "asynchAddImage", но здесь это не проблема.
-(void) burpAnimation {
CCAction *burpAction = [CCSequence actions:
[CCAnimate actionWithAnimation:burpAnim restoreOriginalFrame:NO],
[CCCallFunc actionWithTarget:self selector:@selector(animationDone)],nil];
CGSize winSize = [CCDirector sharedDirector].winSize;
characterSprite = [[Character alloc] initWithSpriteFrameName:@"burp.231.png"];
characterSprite.position = ccp(winSize.width/2, winSize.height/2);
[characterSprite setScale:1.5];
CCAction *particlesAction = [CCSequence actions:
[CCAnimate actionWithAnimation:burpParticlesAnim restoreOriginalFrame:NO],
nil];
burpSprite = [[CCSprite alloc] initWithSpriteFrameName:@"Burp_00003.png"];
burpSprite.position = ccp(winSize.width/2-50, winSize.height/2-80);
[self addChild:characterSprite];
[characterSprite release];
[self addChild:burpSprite];
[burpSprite release];
[characterSprite runAction:burpAction];
[burpSprite runAction:particlesAction];
}
Реальная проблема, с которой я сталкиваюсь, заключается в том, что селектор CCCallFunc вызывается после анимации:
- (void)animationDone {
//Here characterSprite retain count is 2
NSLog(@"B4 stop char rc %d", [characterSprite retainCount]);
[characterSprite stopAllActions];
//Here characterSprite retain count is still 2
NSLog(@"B4 stop char rc %d", [characterSprite retainCount]);
[self removeChild:characterSprite cleanup:YES];
>>> //Here characterSprite retain count is 1 WHY?
>>> NSLog(@"char rc %d", [characterSprite retainCount]);
//Here burpSprite retain count is 2
NSLog(@"particles rc %d", [burpSprite retainCount]);
[burpSprite stopAllActions];
//Here burp retain count is 1
NSLog(@"particles rc %d", [burpSprite retainCount]);
[self removeChild:burpSprite cleanup:YES];
// releases the animation objects
[self unloadBurpAnimation];
//Here burpAnim retainCount = 1
NSLog(@"BURP ANIM rc = %d", [burpAnim retainCount]);
//Here burpParticlesAnim retainCount = 0 , crashes if print here obviously.
//NSLog(@"Particles ANIM rc = %d", [burpParticlesAnim retainCount]);
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
}
Две проблемы:
Несмотря на то, что я удалил characterSprite, я сохранил его количество, равное единице.
Несмотря на то, что я выпустил burpAnim, количество его сохранений равно единице, из-за этого CCSpriteFrameCache не может удалить spriteFrames и, следовательно, текстура также не удаляется.
Обе эти проблемы взаимосвязаны?
Спасибо, ребята, что прочитали это, любая помощь очень ценится.