How to Create a Sprite in the jiugongge stretch mode
In many cases, the four corners of a Sprite must be kept unchanged, such as chat bubbles. The following is an encapsulated BubbleSprite class derived from CCSprite.
Class implementation method:. h file
#import <Foundation/Foundation.h>#import "cocos2d.h"@interface BubbleSprite : CCSprite{ }+(id)spriteWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap;-(id)initWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap;@end
. M file:
#import "BubbleSprite.h"@implementation BubbleSprite+(id)spriteWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap{ return [[[self alloc] initWithFile:file size:size leftCap:leftcap topCap:topcap] autorelease];}-(id)initWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap{ UIImage* image = [UIImage imageNamed:file]; CGImageRef base = image.CGImage; CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, CGImageGetBitsPerComponent(base), 4 * size.width, CGImageGetColorSpace(base), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault); float BASE_COL_X[] = {0,leftcap,leftcap + 1}; float BASE_ROW_Y[] = {0,topcap,topcap +1}; float BASE_COL_WIDTH[] = {leftcap,1,image.size.width - leftcap -1}; float BASE_ROW_HEIGHT[] = {topcap,1,image.size.height - topcap -1}; float TARGET_COL_WIDTH[] = {BASE_COL_WIDTH[0], size.width - BASE_COL_WIDTH[0] - BASE_COL_WIDTH[2], BASE_COL_WIDTH[2]}; float TARGET_ROW_HEIGHT[] = {BASE_ROW_HEIGHT[0], size.height - BASE_ROW_HEIGHT[0] - BASE_ROW_HEIGHT[2], BASE_ROW_HEIGHT[2]}; float TARGET_COL_X[] = {0,TARGET_COL_WIDTH[0],TARGET_COL_WIDTH[0]+TARGET_COL_WIDTH[1]}; float TARGET_ROW_Y[] = {size.height - TARGET_ROW_HEIGHT[0], size.height - TARGET_ROW_HEIGHT[0] - TARGET_ROW_HEIGHT[1], size.height - TARGET_ROW_HEIGHT[0] - TARGET_ROW_HEIGHT[1] - TARGET_ROW_HEIGHT[2]};// int originWidth=image.size.width;// int originHeight=image.size.height;// // float BASE_COL_X[] = {0,leftcap,(originWidth-leftcap)};// float BASE_ROW_Y[] = {0,topcap,(originHeight-topcap)};// float BASE_COL_WIDTH[] = {leftcap,1,leftcap};// float BASE_ROW_HEIGHT[] = {topcap,1,topcap};//// // float TARGET_COL_WIDTH[] = {BASE_COL_WIDTH[0], size.width - BASE_COL_WIDTH[0] - BASE_COL_WIDTH[2], BASE_COL_WIDTH[2]};// // float TARGET_ROW_HEIGHT[] = {BASE_ROW_HEIGHT[0], size.height - BASE_ROW_HEIGHT[0] - BASE_ROW_HEIGHT[2], BASE_ROW_HEIGHT[2]};// // float TARGET_COL_X[] = {0,TARGET_COL_WIDTH[0],size.width-TARGET_COL_WIDTH[0]};// // float TARGET_ROW_Y[] = {size.height - TARGET_ROW_HEIGHT[0],TARGET_ROW_HEIGHT[0],0};// for (int row=0; row<3; row++) { for (int col=0; col<3; col++) { CGRect source = CGRectMake(BASE_COL_X[col], BASE_ROW_Y[row], BASE_COL_WIDTH[col], BASE_ROW_HEIGHT[row]); if (source.origin.x<0) { source.origin.x=0; } if (source.origin.y<0) { source.origin.y=0; } if (source.size.width<0) { source.size.width=0; } if (source.size.height<0) { source.size.height=0; } CGRect target = CGRectMake(TARGET_COL_X[col], TARGET_ROW_Y[row], TARGET_COL_WIDTH[col], TARGET_ROW_HEIGHT[row]); if (target.origin.x<0) { target.origin.x=0; } if (target.origin.y<0) { target.origin.y=0; } if (target.size.width<0) { target.size.width=0; } if (target.size.height<0) { target.size.height=0; } CGImageRef ref = CGImageCreateWithImageInRect(base, source); if (ref) { CGContextDrawImage(context, target, ref); CFRelease(ref); } } } CGImageRef final = CGBitmapContextCreateImage(context); CGContextRelease(context); return [super initWithCGImage:final key:nil];}@end
This class is called as follows:
CGSize bubbleSize;
Int gap_X =
11.0f; // The width of the left and right sides without stretching
Int gap_Y = 15.0f; // keep the height of the upper and lower sides without stretching
BubbleSize. width + = gap_X * 2;
BubbleSize. height + = gap_Y * 2;
The above is what is passed to the BubbleSprite in non-Retina Mode
Parameters of the spriteWithFile function.
To process the Retina mode in a unified manner, add the following code:
Int RETINA =
1;
If (IS_RETINA =
NO)
{
RETINA =
1;
}
Else
{
RETINA =
2;
}
BubbleSize. width = bubbleSize. width * RETINA;
BubbleSize. height = bubbleSize. height * RETINA;
Gap_X = gap_X * RETINA;
Gap_Y = gap_Y * RETINA;
Last call:
// The image name must be manually processed for both HD and non-HD images, because Cocos cannot automatically recognize the two images.
Char temp [30];
Memset (temp, 0,
30 );
If (retina = 1)
{
Sprintf (temp, "chat_bubble.png ");
}
Else
{
Sprintf (temp, "chat_bubble-hd.png ");
}
Nsstring * nspicname = [nsstring
Stringwithcstring: temp encoding: nsutf8stringencoding];
Bubblesprite * bubblesprite = [bubblesprite
Spritewithfile: nspicname
Size: bubblesize leftcap: gap_x
Topcap: gap_y];