如何在Cocos2d中继承AtlasSpriteManager?

发布于 2024-08-11 06:32:03 字数 1464 浏览 5 评论 0原文

我需要创建一些复合精灵,它们会一起移动和旋转。由于可以更改 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,因为这就是返回的内容。嗯嗯。我该如何改变呢?

I need to create some compound sprites that will all move and rotate together. Since it's possible to change the position and rotation of an AtlasSpriteManager I've been trying to subclass so I can create a bunch of shortcuts like

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

internally, it looks a little like this

-(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)];

}

However, when I run the applications, It crashes with the following exception

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

Also, if I remove all the code inside 'MakeComplexSprite' and make it do nothing, I also get the same problem.

It's looking like AtlasSpriteManager just doesn't like to be sub classed. Is this the case? If so, why, and how could I work around it?

UPDATE:

I've found a workaround, by creating an NSObject that contains an atlasSpriteManager. It does the trick, but I would still like to subclass AtlasSpriteManager if possible. I appear to be implementing this exaclty as you describe. I'm creating an instance like this

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

which... now I think about it, means that cSprite is still an AtlasSpriteManager since that's what is being returned. hmmmm. Ho do I change that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水晶透心 2024-08-18 06:32:03

在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;
}

Implement your own spriteManagerWithFile: or compoundSpriteWithFile: in CompoundSprite, which will return an instance of CompoundSprite.

Edit:

Or, you can do something like

[[ComplexSprite alloc] makeComplexSprite];

But then you need to do the 'spriteManagerWithFile:' part also. Like:

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

    // do your ComplexSprite specific initializing here..

    return self;
}
浅浅淡淡 2024-08-18 06:32:03

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

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

CompoundSprite.h

@interface CompoundSprite : AtlasSpriteManager
{

}
- (void)makeComplexSprite;
@end

CompoundSprite.m

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

如果您确实正确设置了子类化,请确保您实际上是在 CompoundSprite 实例上调用 makeComplexSprite,而不是某些实例。意外的其他物体。

另外:

您的代码示例存在内存泄漏。您正在创建两个自动释放的精灵,然后保留它们(这意味着您的类拥有它们的所有权),并且从不释放它们。由于 AddChild: 方法将自动保留对象,因此您可以简单地丢失 retain 调用,一切都会好起来的。

The runtime error you are seeing indicates that your program has tried to send the makeComplexSprite message to an object, but no such method has been defined for that object.

You appear to be sending the makeComplexSprite message to an instance of AtlasSpriteManager instead of an instance of your custom CompoundSprite class. Your example code looks correct, so how are you doing the subclassing? It should look something like this:

CompoundSprite.h:

@interface CompoundSprite : AtlasSpriteManager
{

}
- (void)makeComplexSprite;
@end

CompoundSprite.m:

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

If you do have the subclassing set up properly, make sure you are actually calling makeComplexSprite on an instance of CompoundSprite and not some other object by accident.

Also:

Your code sample has a memory leak. You are creating two autoreleased sprites, then retaining them (which means your class takes ownership of them), and never releasing them. Since the AddChild: method will automatically retain the objects, you can simply lose the retain calls, and everything will be good.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文