如何在Cocos2d中继承AtlasSpriteManager?

时间:2009-11-16 13:49:53

标签: cocoa cocos2d-iphone atlassprites

我需要创建一些可以一起移动和旋转的复合精灵。既然可以改变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不喜欢被分类。是这样的吗?如果是这样,为什么,我怎么能解决它呢?

更新

通过创建包含atlasSpriteManager的NSObject,我找到了一种解决方法。它可以解决这个问题,但如果可能的话,我还是想继承AtlasSpriteManager。正如你所描述的那样,我似乎正在实施这种做法。我正在创建一个像这样的实例

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

...现在我想一想,这意味着cSprite仍然是一个AtlasSpriteManager,因为那是返回的内容。 hmmmm。我可以改变吗?

2 个答案:

答案 0 :(得分:2)

在CompoundSprite中实现你自己的spriteManagerWithFile:或compoundSpriteWithFile:它将返回CompoundSprite的一个实例。

编辑:

或者,您可以执行类似

的操作
[[ComplexSprite alloc] makeComplexSprite];

但是你还需要做'spriteManagerWithFile:'部分。像:

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

    // do your ComplexSprite specific initializing here..

    return self;
}

答案 1 :(得分:1)

您看到的运行时错误表明您的程序已尝试将makeComplexSprite消息发送到对象,但尚未为该对象定义此类方法

您似乎将makeComplexSprite消息发送到AtlasSpriteManager的实例,而不是您的自定义CompoundSprite类的实例。您的示例代码看起来是正确的,那么您如何进行子类化?看起来应该是这样的:

  

CompoundSprite.h

@interface CompoundSprite : AtlasSpriteManager
{

}
- (void)makeComplexSprite;
@end
  

CompoundSprite.m

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

如果确实正确设置了子类,请确保实际上在makeComplexSprite的实例上调用CompoundSprite,而不是偶然地调用其他对象。

同时

您的代码示例存在内存泄漏。你正在创建两个自动释放的精灵,然后保留它们(这意味着你的类拥有它们),并且永远不会释放它们。由于AddChild:方法会自动保留对象,因此您只能丢失retain次来电,一切都会好。