Thanks to liquidfire, I have modified the code he provided for the gradient layer (CCGradientLayer) and extended it a little bit to support specific and diagonal gradients.
This is the original article: CCGradientLayer.
CCGradientLayer.h
#import "cocos2d.h"
typedef enum
{
// each char in the 8-byte value represents the color in the grid
// 00 represents colorFrom
// 01 represents colorTo
// 02 represents colorFrom/colorTo average
CCGradientDirectionT_B = 0x00000101, // top -> bottom
CCGradientDirectionB_T = 0x01010000, // bottom -> top
CCGradientDirectionTR_BL = 0x00020201, // top right -> bottom left
CCGradientDirectionTL_BR = 0x02000102, // top left -> bottom right
CCGradientDirectionBR_TL = 0x02010002, // bottom right -> top left
CCGradientDirectionBL_TR = 0x01020200, // bottom left -> top right
// ^^^^^^^^
// TR BR
// TL BL
} CCGradientDirection;
@interface CCGradientLayer : CCColorLayer
{
}
// creates a full-screen gradient layer
+(id)layerWithColor:(ccColor4B)colorFrom toColor:(ccColor4B)colorTo withDirection:(CCGradientDirection)direction;
// creates a custom width gradient layer
+(id)layerWithColor:(ccColor4B)colorFrom toColor:(ccColor4B)colorTo withDirection:(CCGradientDirection)direction width:(float)width height:(float)height;
// initializes the gradient layer
-(id)initWithColor:(ccColor4B)colorFrom toColor:(ccColor4B)colorTo withDirection:(CCGradientDirection)direction width:(float)width height:(float)height;
// sets the color for a given point (0=BL, 1=BR, 2=TL, 3=TR)
-(void)setColor:(ccColor4B)color atSquareIndex:(int)index;
@end
CCGradientLayer.m
#import "CCGradientLayer.h"
@implementation CCGradientLayer
+(id)layerWithColor:(ccColor4B)colorFrom toColor:(ccColor4B)colorTo withDirection:(CCGradientDirection)direction
{
CGSize size = [[CCDirector sharedDirector] winSize];
return [self layerWithColor:colorFrom toColor:colorTo withDirection:direction width:size.width height:size.height];
}
+(id)layerWithColor:(ccColor4B)colorFrom toColor:(ccColor4B)colorTo withDirection:(CCGradientDirection)direction width:(float)width height:(float)height
{
return [[[self alloc] initWithColor:colorFrom toColor:colorTo withDirection:direction width:width height:height] autorelease];
}
-(id)initWithColor:(ccColor4B)colorFrom toColor:(ccColor4B)colorTo withDirection:(CCGradientDirection)direction width:(float)width height:(float)height;
{
// this char will have a code for each point in the grid (4 points)
// 00 meant colorFrom, 01 means colorTo, 02 means the average of the two
char *charArray = (char *)&direction;
ccColor4B colors[3] = { colorFrom, colorTo, ccc4((colorFrom.r+colorTo.r)/2.0, (colorFrom.g+colorTo.g)/2.0, (colorFrom.b+colorTo.b)/2.0, (colorFrom.a+colorTo.a)/2.0) };
// for each point in the grid
for (int x = 0; x < 4; x++)
{
// get the index of the color that will go in square 0
char colIndex = charArray[x];
// get the color represented by this index
ccColor4B col = colors[(int)colIndex];
// apply it
[self setColor:col atSquareIndex:x];
}
return [self initWithColor:colorFrom width:width height:height];
}
-(void)setColor:(ccColor4B)color atSquareIndex:(int)index
{
// set the color starting from the given index
squareColors[index*4] = color.r;
squareColors[index*4+1] = color.g;
squareColors[index*4+2] = color.b;
squareColors[index*4+3] = color.a;
}
// overridden: we need this not to do anything - extra work that's unneeded
- (void)updateColor
{
return;
}
@end
Here's how to use it:
// create a top-left to bottom-right gradient from red to blue
CCGradientLayer *layer = [CCGradientLayer layerWithColor:ccc4(255,0,0,255) toColor:ccc4(0,0,255,255) withDirection:CCGradientDirectionTL_BR];
// add it to the top layer
[self addChild:layer];
And that it! Again, thanks to liquidfire for the code =).
Enjoy.