在上一篇教程中,我们曾使用有颜色的矩形来绘制地面和天空。通过设置纹理色彩和透明度可以带来很炫的视觉效果。
在这篇教程中,我们将创建一个电影场景,两个武士各自手持光剑对峙。
首先在Xcode中打开RecipeCollection01这个项目。切换到Ch1_ColoringSprites.h,看看以下代码:
//Implementation
@implementation
Ch1_ColoringSprites
-(CCLayer*) runRecipe
{
[self initButtons];
//The Fade
Scene Sprite
CCSprite *fadeSprite =
[CCSprite spriteWithFile:@"blank.png"];
[fadeSprite setOpacity:0];
[fadeSprite setPosition:ccp(240,160)];
[fadeSprite setTextureRect:CGRectMake(0,0,480,320)];
[self addChild:fadeSprite
z:3 tag:TAG_FADE_SPRITE];
//Draw the
sky using blank.png
[self drawColoredSpriteAt:ccp(240,190)
withRect:CGRectMake(0,0,480,260)
withColor:ccc3(150,200,200)
withZ:0];
//Draw the
sun
CCSprite *sun =
[CCSprite spriteWithFile:@"fire.png"];
[sun setPosition:ccp(50,230)];
[sun setScale:3.0f];
[sun setColor:ccc3(255,255,0)];
[self addChild:sun
z:0 tag:TAG_SUN_BG];
//Draw some
mountains in the background
CCSprite *mountains =
[CCSprite spriteWithFile:@"mountains.png"];
[mountains setPosition:ccp(250,200)];
[mountains setScale:0.6f];
[self addChild:mountains
z:0 tag:TAG_MOUNTAIN_BG];
//Add a
gradient below the mountains
CCLayerGradient *groundGradient =
[CCLayerGradient layerWithColor:ccc4(61,33,62,255)
fadingTo:ccc4(65,89,54,255)
alongVector:ccp(0,-1)];
[groundGradient setContentSize:CGSizeMake(480,100)];
[groundGradient setPosition:ccp(0,50)];
[self addChild:groundGradient
z:0 tag:TAG_GROUND_GRADIENT];
//Add a
sinister red glow gradient behind the evil samurai
CCLayerGradient *redGradient =
[CCLayerGradient layerWithColor:ccc4(0,0,0,0)
fadingTo:ccc4(255,0,0,100)
alongVector:ccp(1,0)];
[redGradient setContentSize:CGSizeMake(200,200)];
[redGradient setPosition:ccp(280,60)];
[self addChild:redGradient
z:2 tag:TAG_RED_GRADIENT];
//Draw
dramatic movie bars
[self drawColoredSpriteAt:ccp(240,290)
withRect:CGRectMake(0,0,480,60)
withColor:ccc3(0,0,0)
withZ:2];
[self drawColoredSpriteAt:ccp(240,30)
withRect:CGRectMake(0,0,480,60)
withColor:ccc3(0,0,0)
withZ:2];
//Draw the
good samurai
CCSprite *goodSamurai =
[CCSprite spriteWithFile:@"samurai_good.png"];
goodSamurai.anchorPoint =
ccp(0.5f,0);
[goodSamurai setPosition:ccp(100,70)];
[goodSamurai setScale:0.5f];
[self addChild:goodSamurai
z:1 tag:TAG_GOOD_SAMURAI];
//Draw the
evil samurai
CCSprite *evilSamurai =
[CCSprite spriteWithFile:@"samurai_evil.png"];
evilSamurai.anchorPoint =
ccp(0.5f,0);
[evilSamurai setPosition:ccp(370,70)];
[evilSamurai setFlipX:YES];
[evilSamurai setScale:0.5f];
[self addChild:evilSamurai
z:1 tag:TAG_BAD_SAMURAI];
// Make the
swords glow
[self glowAt:ccp(230,280)
withScale:CGSizeMake(3.0f,
11.0f)
withColor:ccc3(0,230,255)
withRotation:45.0f withSprite:goodSamurai];
[self glowAt:ccp(70,280)
withScale:CGSizeMake(3.0f,
11.0f)
withColor:ccc3(255,200,2)
withRotation:-45.0f withSprite:evilSamurai];
return
self;
}
-(void) initButtons
{
[CCMenuItemFont setFontSize:16];
//'Fade to
Black' button
CCMenuItemFont* fadeToBlack =
[CCMenuItemFont itemFromString:@"FADE TO BLACK" target:self selector:@selector(fadeToBlackCallback:)];
CCMenu
*fadeToBlackMenu =
[CCMenu menuWithItems:fadeToBlack,
nil];
fadeToBlackMenu.position =
ccp(
180
,
20
);
[self addChild:fadeToBlackMenu
z:4 tag:TAG_FADE_TO_BLACK];
//'Fade to
White' button
CCMenuItemFont* fadeToWhite =
[CCMenuItemFont itemFromString:@"FADE TO WHITE" target:self selector:@selector(fadeToWhiteCallback:)];
CCMenu
*fadeToWhiteMenu =
[CCMenu menuWithItems:fadeToWhite,
nil];
fadeToWhiteMenu.position =
ccp(
300
,
20
);
[self addChild:fadeToWhiteMenu
z:4 tag:TAG_FADE_TO_WHITE];
}
-(void)
fadeToBlackCallback:(id)sender
{
CCSprite *fadeSprite =
[self getChildByTag:TAG_FADE_SPRITE];
[fadeSprite stopAllActions];
[fadeSprite setColor:ccc3(0,0,0)];
[fadeSprite setOpacity:0.0f];
[fadeSprite runAction:
[CCSequence actions:[CCFadeIn actionWithDuration:2.0f],
[CCFadeOut actionWithDuration:2.0f],
nil]
];
}
-(void)
fadeToWhiteCallback:(id)sender
{
CCSprite *fadeSprite =
[self getChildByTag:TAG_FADE_SPRITE];
[fadeSprite stopAllActions];
[fadeSprite setColor:ccc3(255,255,255)];
[fadeSprite setOpacity:0.0f];
[fadeSprite runAction:
[CCSequence actions:[CCFadeIn actionWithDuration:2.0f],
[CCFadeOut actionWithDuration:2.0f],
nil]
];
}
-(void)
drawColoredSpriteAt:(CGPoint)position
withRect:(CGRect)rect
withColor:(ccColor3B)color
withZ:(float)z {
CCSprite *sprite =
[CCSprite spriteWithFile:@"blank.png"];
[sprite setPosition:position];
[sprite setTextureRect:rect];
[sprite setColor:color];
[self addChild:sprite];
//Set Z
Order
[self reorderChild:sprite
z:z];
}
-(void)
glowAt:(CGPoint)position
withScale:(CGSize)size
withColor:(ccColor3B)color
withRotation:(float)rotation
withSprite:(CCSprite*)sprite
{
CCSprite *glowSprite =
[CCSprite spriteWithFile:@"fire.png"];
[glowSprite setColor:color];
[glowSprite setPosition:position];
[glowSprite setRotation:rotation];
[glowSprite setBlendFunc:
(ccBlendFunc) {
GL_ONE,
GL_ONE
}];
[glowSprite runAction:
[CCRepeatForever actionWithAction:
[CCSequence actions:[CCScaleTo actionWithDuration:0.9f scaleX:size.width scaleY:size.height],
[CCScaleTo actionWithDuration:0.9f scaleX:size.width*0.75f scaleY:size.height*0.75f],
nil] ]
];
[glowSprite runAction:
[CCRepeatForever actionWithAction:
[CCSequence actions:[CCFadeTo actionWithDuration:0.9f opacity:150],
[CCFadeTo actionWithDuration:0.9f opacity:255],
nil] ]
];
[sprite addChild:glowSprite];
}
对于已经学过cocos2d的开发者来说,上面的很多代码基本上都很熟悉了,下面来大概解释下:
1.
设置精灵的色彩
最简单的方法当然是使用以下方法直接设置精灵的色彩:
-(void) setColor:(ccColor3B)color;
ccColor3B是一个C结构体,包含了3个GLubyte变量,其定义如下:
typedef struct _ccColor3B
{
GLubyte r;
GLubyte g;
GLubyte b;
} ccColor3B;
通常使用以下的辅助宏定义来创建ccColor3G结构:
ccColor3B ccc3(const GLubyte r, const GLubyte
g, const GLubyte
b);
此外Cocos2d里面还指定了一些预定义的色彩作为常数,包括:
ccWHITE,
ccYELLOW, ccBLUE, ccGREEN, ccRED,
ccMAGENTA, ccBLACK, ccORANGE, ccGRAY
2.
渐淡到某种色彩:
为了让场景渐淡到某个特定的色彩,我们使用blank.png这种技巧。首先我们需要绘制一些和场景一样大的精灵,然后将精灵的色彩设置我们需要渐淡到的色彩,然后运行CCFadeIn动作来使得该精灵渐淡到某个色彩:
[fadeSprite
setColor:ccc3(255,255,255)];
[fadeSprite setOpacity:0.0f];
[fadeSprite runAction: [CCFadeIn actionWithDuration:2.0f] ];
3.
使用CCLayerGradient
CCLayerGradient继承自CCLayerColor,使用该类我们可以通过代码创建渐变效果。
我们通过以下方法来让背景中的山脉和武士所站立的地面间产生渐变:
//Add a
gradient below the mountains
CCLayerGradient *groundGradient =
[CCLayerGradient layerWithColor:ccc4(61,33,62,255)
fadingTo:ccc4(65,89,54,255)
alongVector:ccp(0,-1)];
[groundGradient setContentSize:CGSizeMake(480,100)];
[groundGradient setPosition:ccp(0,50)];
[self addChild:groundGradient
z:0 tag:TAG_GROUND_GRADIENT];
使用CCLayerGradient可以很好的控制透明度和色彩,比如大家可以看到在右侧武士之后有代表邪恶的红色光晕。
4.
让精灵产生光晕
为了让示例中的光剑产生光晕效果,我们对色彩进行了精巧的操作,包括添加了色彩混合(使用opengl),以及添加了淡入和缩放动作。首先我们加载了fire.png,通过更改它在X和Y轴上的大小,可以让它变窄或变宽。一旦我们得到了所需的缩放比率,就可以让精灵不断缩放和淡入。同时我们使用了色彩混合模式。最后让该精灵执行一个序列动作以产生这种效果:
CCSprite *glowSprite =
[CCSprite spriteWithFile:@"fire.png"];
[glowSprite setColor:color];
[glowSprite setPosition:position];
[glowSprite setRotation:rotation];
[glowSprite setBlendFunc:
(ccBlendFunc) {
GL_ONE,
GL_ONE
}];
[glowSprite runAction:
[CCRepeatForever actionWithAction:
[CCSequence actions:[CCScaleTo actionWithDuration:0.9f scaleX:size.width scaleY:size.height],
[CCScaleTo actionWithDuration:0.9f scaleX:size.width*0.75f scaleY:size.height*0.75f],
nil] ]
];
[glowSprite runAction:
[CCRepeatForever actionWithAction:
[CCSequence actions:[CCFadeTo actionWithDuration:0.9f opacity:150],
[CCFadeTo actionWithDuration:0.9f opacity:255],
nil] ]
];
[sprite addChild:glowSprite];