Well moving ahead with Category and trying my hands on them, I found its better to have some code reference here to serve myself in the need.
I was working with Sparrow framework for my opensource iphone game MathIsFun2. And suddenly I needed to add some functionality to the Sprite class that Sparrow has. This made a situation to have a Category.
The example code here, is not exactly the same as in the game, I changed the Category and code here, so as to best fit for general purpose.
The code and example here is just to make the understanding of Category and not to show how we are going to do a certain task in it (as we are drawing a circle here). There may be better way to do, what we are going to do here (creating a circle), but lets concentrate and see how Categories work.
The point here is, I needed a “draw circle” method in Sparrow’s SPSprite. I went ahead and made a category named “SPSprite+Circle” and the two files are “SPSprite+Circle.h”,”SPSprite+Circle.m”. Lets see how these files look from inside.
The interface file “SPSprite+Circle.h”
#import
#import "Sparrow.h"
@interface SPSprite(Circle)
-(void)makeCircle:(int)radius
WithThickness:(int)thickness
AndColor:(uint)color;
@end
The implementation file “SPSprite+Circle.m”
#import "SPSprite+Circle.h"
@implementation SPSprite(Circle)
-(void)makeCircle:(int)radius
WithThickness:(int)thickness
AndColor:(uint)color
{
for (int i=0; i<=360; i++) {
SPQuad *q=[SPQuad quadWithWidth:thickness height:3];
q.color = color;
q.x=radius*cos(i);
q.y=radius*sin(i);
q.rotation=i;
[self addChild:q];
}
}
@end
Thats all, I needed a method to draw a circle in my sprite, and made a Category, which handles that. Now where ever I have imported SPSprite, I have to replace that with "SPSprite+Circle". Rest of the implementations remain the same.
Lets see, the usage code
//first import in the interface .h file
#import "SPSprite+Circle.h"
//on the implementation .m file write down the below code
//where you think you want a circle
SPSprite *s=[[SPSprite alloc] init];
[s makeCircle:50 WithThickness:30 AndColor:0xffffff];
[self addChild:s];
s.x=80;
s.y=80;
You can see the clear advantage. We are making an SPSprite and calling the method on it. The same method "makeCircle: WithThickness: AndColor:", which we have declared in our Category now directly available to the SPSprite Object.
Now lets try the more confusing one. I have another class named “SsaumyaSprite”, which is a child class of “SPSprite”.
#import
#import "Sparrow.h"
@interface SsaumyaSprite : SPSprite
{
}
- (id)initWithSqare;
-(id)initWithCircle:(int)radius AndThickness:(int)thick;
-(void)makeCircle:(int)radius withThickness:(int)thickness;
@end
So it has all these method implementations in its implementation file as well. Now lets try and call our new method which was added as a Category. The same implementation file will look as below
//first import in the interface .h file
#import "SsaumyaSprite.h"
#import "SPSprite+Circle.h"
//on the implementation .m file write down the below code
//SPSprite *s=[[SPSprite alloc] init];
SsaumyaSprite *s=[[SsaumyaSprite alloc] initWithCircle:100 AndThickness:1];
[s makeCircle:50 WithThickness:30 AndColor:0xffffff];
[self addChild:s];
s.x=80;
s.y=80;
Looking carefully into the code will show you that now we are not making “SPSprite” object but “SsaumyaSprite” object. Again, after that all the code are the same. The child class also gets the added method to the base class ( by Category ).
I hope that clears out a lot of confusion and shows the potential of Category in objectiveC.
The source code for this example Category are available at Github.
My opensource gameMathIsFun2 is available at Github too.
Hope to see some gaming around it