Position a CCSprite in any way imaginable 1

In a couple of my projects I needed to be able to position and scale or rotate based on different anchor points on the same sprite.

For example, I am using CCLabelTTF and I’m trying to highlight different parts of a word. So I am scaling or rotating the first letter in the word without changing the last two letters in the word. (I create two CCLabelTTF objects for this.) But I want to position the first letter by it’s bottom right hand corner, and line that up with the bottom left hand corner of the last two letters. In doing this I quickly run into problems where I am changing the anchor point according to my needs, which necessitates calculating the changes to the position so that it doesn’t move according to the new anchor point. I realized that what I wanted was a set of methods for all my sprites where I could reset the position by any corner or center, but without changing the anchor point.

This was a perfect opportunity to learn how categories work. In Objective-C, a category adds a method to an existing class. They are very handy. So I wrote a set of methods that will return or set position of all four corners of the sprite, or it’s center. Because CCLableTTF is a child of CCSprite, these methods also work there. In fact they’ll work on any subclass of CCSprite. (Maybe I should have done then on CCNode, but I wasn’t thinking that carefully about it at the time).

Anyway, the code looks at the current anchor point, calculates the difference between the anchor point and the corner you are trying to set or return, and works out the difference so that the anchor point is set appropriately depending on the set position of the corner.

CCSprite+position.h:

#import "cocos2d.h"

@interface CCSprite (position)

-(CGPoint)bottomLeft;
-(CGPoint)topLeft;
-(CGPoint)bottomRight;
-(CGPoint)topRight;
-(CGPoint)centerP;

-(void)setBottomLeft:(CGPoint)p;
-(void)setTopLeft:(CGPoint)p;
-(void)setBottomRight:(CGPoint)p;
-(void)setTopRight:(CGPoint)p;
-(void)setCenterP:(CGPoint)p;

@end

CCSprite+position.m:

#import "CCSprite+position.h"

@implementation CCSprite (position)

-(CGPoint)bottomRight {
float x = (self.contentSize.width * (1-self.anchorPoint.x)) + self.position.x;
float y = -(self.contentSize.height * self.anchorPoint.y) + self.position.y;
return ccp(x, y);
}

-(CGPoint)bottomLeft {
float x = -(self.contentSize.width * self.anchorPoint.x) + self.position.x;
float y = -(self.contentSize.height * self.anchorPoint.y) + self.position.y;
return ccp(x, y);
}

-(CGPoint)topRight {
float x = (self.contentSize.width * (1-self.anchorPoint.x)) + self.position.x;
float y = (self.contentSize.height * (1-self.anchorPoint.y)) + self.position.y;
return ccp(x, y);
}

-(CGPoint)topLeft {
float x = -(self.contentSize.width * self.anchorPoint.x) + self.position.x;
float y = (self.contentSize.height * (1-self.anchorPoint.y)) + self.position.y;
return ccp(x, y);
}

-(CGPoint)centerP {
CGPoint BL = [self bottomLeft];
CGPoint TR = [self topRight];
float x = self.contentSize.width / 2 + BL.x;
float y = self.contentSize.height / 2 + TR.y;
return ccp(x, y);
}

-(void)setBottomLeft:(CGPoint)p {
float x = (self.contentSize.width * self.anchorPoint.x) + p.x;
float y = (self.contentSize.height * self.anchorPoint.y) + p.y;
self.position = ccp(x, y);
}

-(void)setTopLeft:(CGPoint)p {
float x = (self.contentSize.width * self.anchorPoint.x) + p.x;
float y = -(self.contentSize.height * (1-self.anchorPoint.y)) + p.y;
self.position = ccp(x, y);
}

-(void)setBottomRight:(CGPoint)p {
float x = -(self.contentSize.width * (1-self.anchorPoint.x)) + p.x;
float y = (self.contentSize.height * self.anchorPoint.y) + p.y;
self.position = ccp(x, y);
}

-(void)setTopRight:(CGPoint)p {
float x = -(self.contentSize.width * (1-self.anchorPoint.x)) + p.x;
float y = -(self.contentSize.height * (1-self.anchorPoint.y)) + p.y;
self.position = ccp(x, y);
}

-(void)setCenterP:(CGPoint)p {
float x = p.x + (self.contentSize.width * (self.anchorPoint.x - 0.5));
float y = p.y + (self.contentSize.height * (self.anchorPoint.y - 0.5));
self.position = ccp(x, y);
}

@end

Let me know if you find these useful, or if there’s an easier way that I didn’t think of in trying to solve my problem.

One comment on “Position a CCSprite in any way imaginable

Leave a Reply to Anon Cancel Reply