Reputation: 9586
Abused topic considering the posts (e.g this or this) but I still don't quiet manage to get what I want.
I am working on a shooter game and I would like to light up my enemies when they get hit (as well as the player).
If I run the following my sprite doesn't get white. Is this the right direction?
-(void) gothitAnimation
{
ccColor3B originalColor = self.color;
id delay = [CCDelayTime actionWithDuration:0.4f];
[self runAction:[CCSequence actions: [CCTintTo actionWithDuration:0.01f red:255 green:240 blue:240], delay, [CCTintTo actionWithDuration:0.01f red:originalColor.r green:originalColor.g blue:originalColor.b] , nil]];
}
I have tried running only the CCTintTo action and it does work only with colours different than white.
I have found Arodius's game demo and it seem to me that there the player ship gets set multiple times to invisible and visible in a short sequence of actions when hit or in lower energy levels (see this demo). Also the enemy get a light effect when hit.
Any idea on how this has been achieved? Did the developer use the CCTintTo action or something else? I know that for the explosion he used ParticleEffects.
Upvotes: 0
Views: 1140
Reputation: 5703
I recently needed to do the same, and didn't want to deal with pixel shaders. I figured I could mess with how the texture is blended into the scene to get some sort of white flash out of it.
So, I figured out a reasonable light-flash effect by repeatedly changing the sprite's Destination glBlend function from GL_ONE_MINUS_SRC_ALPHA to GL_ONE, and then back.
Here's my toggle method:
-(void)toggleBlendFlash {
if (sprite_) {
ccBlendFunc blendFunc = sprite_.blendFunc;
if (blendFunc.dst == GL_ONE_MINUS_SRC_ALPHA) {
blendFunc.dst = GL_ONE; //flash white
} else {
blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA; //default
}
sprite_.blendFunc = blendFunc;
}
}
Here's my flashing sequence:
CCSequence *sequence =
[CCSequence actions:
[CCCallFunc actionWithTarget:targetEnemy selector:@selector(toggleBlendFlash)],
[CCDelayTime actionWithDuration:0.3],
[CCCallFunc actionWithTarget:targetEnemy selector:@selector(toggleBlendFlash)],
[CCDelayTime actionWithDuration:0.2], nil ];
It may not look perfect for your situation, but give it a try!
EDIT 1: Also, check these links out for more info/resources:
EDIT 2:
Of course, I just realized that if your sprite is animating between different CCTexture2D objects (e.g. you have 1 file per frame), then it resets your blendFunc for every frame, which means you have to either create a category or a subclass for CCSprite or CCAnimate to re-apply your custom blendFunc... so I guess its not as quick of a solution as I had originally thought.
Upvotes: 2
Reputation: 64478
The default tint color for sprites is white. So you can't tint to white or make the sprite appear brighter with tinting.
Blinking can be achieved by setting the visible property on and off at an interval. One way to do that is to use the CCBlink action.
Your best bet is to use a particle effect. You can only achieve a true lighting effect if you're using cocos2d 2.0 and write a fragment shader for this particular effect.
Upvotes: 3