Skip to content

Instantly share code, notes, and snippets.

@nsxdavid
Created July 27, 2011 04:35
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save nsxdavid/1108677 to your computer and use it in GitHub Desktop.
Save nsxdavid/1108677 to your computer and use it in GitHub Desktop.
Scale9Sprite - A Cocos2d 9-Slice Sprite
//
// Scale9Sprite.h
//
// Public domain. Use in anyway you see fit. No waranties of any kind express or implied.
// Based off work of Steve Oldmeadow and Jose Antonio Andújar Clavell
//
//
// Creates a 9-slice sprite for cocos2d
//
// Parameters
//
// file
// The name of the texture file
//
// rect
// The rectangle that describes the sub-part of the texture that is the whole image.
// If the shape is the whole texture, set this to the texture's full rect
//
//
// centerRegion
// Defines the inside part of the 9-slice. This part will scale X and Y. The top and bottom borders scale X only.
// The left and right borders scale Y only. The four outside corners do not scale at all.
//
// This rectangle must represent a space that is inside what is specified by the rect param
//
//
// Once the sprite is created, you can then call [mySprite setContentSize:newRect] to resize the
// the sprite will all it's 9-slice goodness intract. Respects anchorPoint too.
#import "Game.h"
@interface Scale9Sprite : CCNode <CCRGBAProtocol> {
CGRect rect_;
CCSpriteBatchNode *scale9Image;
CCSprite *topLeft;
CCSprite *top;
CCSprite *topRight;
CCSprite *left;
CCSprite *centre;
CCSprite *right;
CCSprite *bottomLeft;
CCSprite *bottom;
CCSprite *bottomRight;
// texture RGBA
GLubyte opacity;
ccColor3B color;
BOOL opacityModifyRGB_;
}
-(id) initWithFile:(NSString*)file rect:(CGRect) rect centreRegion:(CGRect)centreRegion;
/** conforms to CocosNodeRGBA protocol */
@property (nonatomic,readwrite) GLubyte opacity;
/** conforms to CocosNodeRGBA protocol */
@property (nonatomic,readwrite) ccColor3B color;
@end
//
// Scale9Sprite.m
//
// Creates a 9-slice sprite.
#import "Scale9Sprite.h"
@implementation Scale9Sprite
@synthesize opacity, color;
enum positions {
pCentre = 0,
pTop,
pLeft,
pRight,
pBottom,
pTopRight,
pTopLeft,
pBottomRight,
pBottomLeft
};
CGSize baseSize;
CGRect resizableRegion;
-(id) initWithFile:(NSString*)file rect:(CGRect) rect centreRegion:(CGRect)centreRegion {
if( (self=[super init]) ) {
anchorPoint_ = ccp(0.5f,0.5f);
rect_ = rect;
scale9Image = [[CCSpriteBatchNode alloc] initWithFile:file capacity:9];
//CGSize imageSize = scale9Image.texture.contentSize;
//Set up centre sprite
centre = [[CCSprite alloc] initWithBatchNode:scale9Image rect:centreRegion];
[scale9Image addChild:centre z:0 tag:pCentre];
float l = rect_.origin.x;
float t = rect_.origin.y;
float h = rect_.size.height;
float w = rect_.size.width;
//top
top = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(centreRegion.origin.x,
t,
centreRegion.size.width,
centreRegion.origin.y-t)
];
[scale9Image addChild:top z:1 tag:pTop];
//bottom
bottom = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(centreRegion.origin.x,
centreRegion.origin.y + centreRegion.size.height,
centreRegion.size.width,
h - (centreRegion.origin.y - t + centreRegion.size.height))
];
[scale9Image addChild:bottom z:1 tag:pBottom];
//left
left = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(l,
centreRegion.origin.y,
centreRegion.origin.x - l,
centreRegion.size.height)
];
[scale9Image addChild:left z:1 tag:pLeft];
//right
right = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(centreRegion.origin.x + centreRegion.size.width,
centreRegion.origin.y,
w - (centreRegion.origin.x - l + centreRegion.size.width),
centreRegion.size.height)
];
[scale9Image addChild:right z:1 tag:pRight];
//top left
topLeft = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(l,
t,
centreRegion.origin.x - l,
centreRegion.origin.y - t)
];
[scale9Image addChild:topLeft z:2 tag:pTopLeft];
//top right
topRight = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(centreRegion.origin.x + centreRegion.size.width,
t,
w - (centreRegion.origin.x - l + centreRegion.size.width),
centreRegion.origin.y - t)
];
[scale9Image addChild:topRight z:2 tag:pTopRight];
//bottom left
bottomLeft = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(l,
centreRegion.origin.y + centreRegion.size.height,
centreRegion.origin.x - l,
h - (centreRegion.origin.y - t + centreRegion.size.height))
];
[scale9Image addChild:bottomLeft z:2 tag:pBottomLeft];
//bottom right
bottomRight = [[CCSprite alloc]
initWithBatchNode:scale9Image
rect:CGRectMake(centreRegion.origin.x + centreRegion.size.width,
centreRegion.origin.y + centreRegion.size.height,
w - (centreRegion.origin.x - l + centreRegion.size.width),
h - (centreRegion.origin.y - t + centreRegion.size.height))
];
[scale9Image addChild:bottomRight z:2 tag:pBottomRight];
baseSize = rect.size;
resizableRegion = centreRegion;
[self setContentSize:rect_.size];
[self addChild:scale9Image];
}
return self;
}
-(void) dealloc
{
[topLeft release];
[top release];
[topRight release];
[left release];
[centre release];
[right release];
[bottomLeft release];
[bottom release];
[bottomRight release];
[scale9Image release];
[super dealloc];
}
-(void) setContentSize:(CGSize)size
{
[super setContentSize:size];
float sizableWidth = size.width - topLeft.contentSize.width - topRight.contentSize.width;
float sizableHeight = size.height - topLeft.contentSize.height - bottomRight.contentSize.height;
float horizontalScale = sizableWidth/centre.contentSize.width;
float verticalScale = sizableHeight/centre.contentSize.height;
centre.scaleX = horizontalScale;
centre.scaleY = verticalScale;
float rescaledWidth = centre.contentSize.width * horizontalScale;
float rescaledHeight = centre.contentSize.height * verticalScale;
//Position corners
//[self setAnchorPoint:CGPointMake(0.5f,0.5f)];
float despx = size.width*0.5f;
float despy = size.height*0.5f;
//Position corners
[topLeft setPosition:CGPointMake(-rescaledWidth/2 - topLeft.contentSize.width/2 +despx, rescaledHeight/2 + topLeft.contentSize.height*0.5 + despy) ];
[topRight setPosition:CGPointMake(rescaledWidth/2 + topRight.contentSize.width/2 +despx, rescaledHeight/2 + topRight.contentSize.height*0.5 + despy)];
[bottomLeft setPosition:CGPointMake(-rescaledWidth/2 - bottomLeft.contentSize.width/2 + despx, -rescaledHeight/2 - bottomLeft.contentSize.height*0.5 + despy)];
[bottomRight setPosition:CGPointMake(rescaledWidth/2 + bottomRight.contentSize.width/2 + despx, -rescaledHeight/2 + -bottomRight.contentSize.height*0.5 + despy)];
top.scaleX = horizontalScale;
[top setPosition:CGPointMake(0+despx,rescaledHeight/2 + topLeft.contentSize.height*0.5 + despy)];
bottom.scaleX = horizontalScale;
[bottom setPosition:CGPointMake(0+despx,-rescaledHeight/2 - bottomLeft.contentSize.height*0.5 + despy)];
left.scaleY = verticalScale;
[left setPosition:CGPointMake(-rescaledWidth/2 - topLeft.contentSize.width/2 +despx, 0 + despy)];
right.scaleY = verticalScale;
[right setPosition:CGPointMake(rescaledWidth/2 + topRight.contentSize.width/2 +despx, 0 + despy)];
[centre setPosition:CGPointMake(despx, despy)];
}
-(void) draw {
[scale9Image draw];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment