Как создать подкласс AtlasSpriteManager в Cocos2d? - PullRequest
1 голос
/ 16 ноября 2009

Мне нужно создать несколько составных спрайтов, которые будут двигаться и вращаться вместе. Поскольку возможно изменить положение и вращение AtlasSpriteManager, который я пытался создать в подклассе, я могу создать несколько ярлыков, например

CompoundSprite *cSprite = [CompoundSprite spriteManagerWithFile:@"sprites.png"];
[cSprite makeComplexSprite];

внутренне это выглядит примерно так

-(void)makeComplexSprite
{
        AtlasSprite *sp1 = [[AtlasSprite spriteWithRect:CGRectMake(0, 0, 64, 64)       
                             spriteManager:self] retain];
        AtlasSprite *sp2 = [[AtlasSprite spriteWithRect:CGRectMake(0, 0, 64, 64) 
                             spriteManager:self] retain];

    [self addChild:sp1];
    [self addChild:sp2];


    [sp1 setPosition:CGPointMake(0,0)];
    [sp2 setPosition:CGPointMake(64,0)];

}

Однако, когда я запускаю приложения, происходит сбой со следующим исключением

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '*** -[AtlasSpriteManager makeComplexSprite]: unrecognized selector sent to 
instance 0x107e1c0

Кроме того, если я удалю весь код внутри 'MakeComplexSprite' и заставлю его ничего не делать, у меня тоже возникнет та же проблема.

Похоже, что AtlasSpriteManager просто не любит быть подклассом. Это тот случай? Если так, то почему и как я мог обойти это?

UPDATE

Я нашел обходной путь, создав NSObject, который содержит atlasSpriteManager. Это делает свое дело, но я все же хотел бы подкласс AtlasSpriteManager, если это возможно. Я, кажется, реализую эту точность, как вы описываете. Я создаю экземпляр, подобный этому

CompoundSprite *cSprite = [CompoundSprite spriteManagerWithFile:@"file.png"]; 
[cSprite makeBox]; 

что ... теперь я думаю об этом, означает, что cSprite все еще является AtlasSpriteManager, так как это то, что возвращается. хммм. Как мне это изменить?

Ответы [ 2 ]

2 голосов
/ 16 ноября 2009

Реализуйте свой собственный spriteManagerWithFile: или componentSpriteWithFile: в CompoundSprite, который вернет экземпляр CompoundSprite.

Edit:

Или вы можете сделать что-то вроде

[[ComplexSprite alloc] makeComplexSprite];

Но тогда вам нужно также выполнить часть spriteManagerWithFile :. Как:

-(id)makeComplexSpriteWithFile:(NSString*)file
{
    if (! (self = [super initWithSpriteManager:..capacity:..]))
       return nil;

    // do your ComplexSprite specific initializing here..

    return self;
}
1 голос
/ 16 ноября 2009

Ошибка во время выполнения означает, что ваша программа пыталась отправить объекту сообщение makeComplexSprite, но такой метод для этого объекта не определен .

Вы, похоже, отправляете сообщение makeComplexSprite экземпляру AtlasSpriteManager вместо экземпляра вашего пользовательского класса CompoundSprite. Ваш пример кода выглядит правильно, так как вы делаете подклассы? Это должно выглядеть примерно так:

CompoundSprite.h :

@interface CompoundSprite : AtlasSpriteManager
{

}
- (void)makeComplexSprite;
@end

CompoundSprite.m :

@interface CompoundSprite
- (void)makeComplexSprite
{
    ...
}
@end

Если вы правильно настроили подклассы, убедитесь, что вы действительно вызываете makeComplexSprite для экземпляра CompoundSprite, а не случайно какой-то другой объект.

Также:

Ваш пример кода имеет утечку памяти. Вы создаете два автоматически выпущенных спрайта, затем сохраняете их (что означает, что ваш класс становится их владельцем), и никогда не выпускаете их. Так как метод AddChild: автоматически сохранит объекты, вы можете просто потерять вызовы retain, и все будет хорошо.

...