我需要创建一些可以一起移动和旋转的复合精灵。既然可以改变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。我可以改变吗?
答案 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
次来电,一切都会好。