English 中文(简体)
How to subclass AtlasSpriteManager in Cocos2d?
原标题:

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?

最佳回答

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;
}
问题回答

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.





相关问题
Taking picture with QTCaptureView

Is it possible to simply take a picture and save it somewhere using a QTCaptureView and Apple s built-in iSight? I ve seen lots of tutorials on recording video but none on simply taking a picture. Any ...

Controlling OSX windows

I m trying to control windows of a foreign OSX applications from my application. I d like to 1. move the windows on the screen 2. resize the windows on the screen 3. change the currently active window ...

objective-c: Calling a void function from another controller

i have a void, like -(void) doSomething in a specific controller. i can call it in this controller via [self doSomething], but i don t know how to call this void from another .m file. I want to call ...

NSUndoManager and runModalForWindow:

I have a simple Core Data app which displays a list of entities in the main window. To create or add new entities, I use a second modal window with a separate managed object context so changes can be ...

NSMutableArray values becoming "invalid"

I m trying to show a database information in a tableview and then the detailed information in a view my problem is as follow: I created a NSMutableArray: NSMutableArray *myArray = [[NSMutableArray ...

How to get a flash url in a webpage using a webframe?

As we know , When we load frame from webpage of safari, we will invoke the delegate methods of webkit informal protocol(WebFrameLoadDelegate): webView:didStartProvisionalLoadForFrame: webView:...

热门标签