Tuesday, November 24, 2009

Primitive Sprites with Cocos2d

Cocos2d makes it easy to load an image into a Sprite and move it around the scene. But, what if you want some primitive sprites like circles, squares, or any other line-drawn shape. Cocos2d does provide a "drawing primitives" library to actually draw the line, circle, etc., but how do you use it like a Sprite along with your other sprites.

The answer is to create your own class that extends CocosNode and provide the simple primitive design. For example, here is a simple implementation called CircleNode. This gives you the simple ability to create a Circle of a specified radius and color, and to then treat this like any other Sprite (e.g. add it as a child to your scene, set it's position, etc.).

First, here is the class definition for CircleNode:


#import "cocos2d.h"


@interface CircleNode : CocosNode {

int radius;
int colorCode;
int priority;

}

@property (nonatomic, assign) int colorCode;
@property (nonatomic, assign) int priority;


-(id)init: (int)radius colorCode:(int)c priority:(int)pri;
-(void)draw;


@end


Finally, here is the example implementation:

#import "CircleNode.h"


@implementation CircleNode

@synthesize colorCode;
@synthesize priority;


-(id)init: (int)rad colorCode:(int)color priority:(int)pri {
if( (self=[super init]) ) {
radius = rad;
self.colorCode = color;
self.priority = pri;

// set up the geometry of this sprite
// this is necessary so the sprite indicates it's body size
// relative the center point (position)
CGSize size;
size.width = 2 * rad;
size.height = 2 * rad;
self.contentSize = size;
self.anchorPoint = ccp(0.5, 0.5);

}
return self;
}

-(void)draw {

glLineWidth(4);


//red
if (colorCode == 0) {
glColor4ub(255, 0, 0, 255);
}
// yellow
if (colorCode == 1) {
glColor4ub(255, 255, 0, 255);
}
// green
if (colorCode == 2) {
glColor4ub(0, 255, 0, 255);
}

// coordinates are relative to this sprites "position"
// the draw primitives origin are in the lower left corner relative to the anchor point
// so the center is "radius" pixels over and up on the x,y axis
CGPoint circleCenter = ccp(radius,radius);
drawCircle( circleCenter, radius, 0, 30, NO);

}

@end


There are a few important things to point out....

The draw method is where the magic happens. Simply put your drawing calls in there.

As you play with this implementation, one thing to get right is the physical characteristics of the "Sprite". For example, you need to set the appropriate "content size" of the object so that if you are detecting a "touch" of this object, the object's bounding rectangle is correct. Next, set the Anchor Point accordingly. This will establish the coordinate system for your drawing. By setting the anchor as (0.5,0.5), I am setting the anchor in the middle of the object. The (0,0) point is now in the bottom left of the object. In order to draw at the center of the circle, you would use ccp(radius,radius) as the middle of the circle.

With this simple extension of CocosNode, I have created a CircleNode that can be used like any other Sprite in the scene. You can use this basic technique to come up with your own primitive drawing Sprites. I have used it to create Arrows, and more complex drawing elements.

Enjoy!

No comments:

Post a Comment