Reputation: 16308
The SKAction
colorizeWithColor:
does as per the docs only work with SKSpriteNode
, so what do we do with SKLabelNode
? SKLabelNode does have both color
and colorBlendFactor
properties that can be set statically. Is there some way to animate this with SKAction?
My current approach is to render a SKLabelNode to a texture using SKView's instance method textureFromNode, but just get nil texture out of that atm :-(
Update: What do you know. I think I found out the problem with the texture rendering. It's not possible to redner a texture in the init method of SKScene, because self.view is nil at that point. So I tried it in didMoveToView and voila, texture rendered. Thanks anyway :-)
Upvotes: 2
Views: 4261
Reputation: 185
Maybe somebody will find this useful.
func changeColorForLabelNode(labelNode: SKLabelNode, toColor: SKColor, withDuration: NSTimeInterval) {
labelNode.runAction(SKAction.customActionWithDuration(withDuration, actionBlock: {
node, elapsedTime in
let label = node as SKLabelNode
let toColorComponents = CGColorGetComponents(toColor.CGColor)
let fromColorComponents = CGColorGetComponents(label.fontColor.CGColor)
let finalRed = fromColorComponents[0] + (toColorComponents[0] - fromColorComponents[0])*CGFloat(elapsedTime / CGFloat(withDuration))
let finalGreen = fromColorComponents[1] + (toColorComponents[1] - fromColorComponents[1])*CGFloat(elapsedTime / CGFloat(withDuration))
let finalBlue = fromColorComponents[2] + (toColorComponents[2] - fromColorComponents[2])*CGFloat(elapsedTime / CGFloat(withDuration))
let finalAlpha = fromColorComponents[3] + (toColorComponents[3] - fromColorComponents[3])*CGFloat(elapsedTime / CGFloat(withDuration))
labelNode.fontColor = SKColor(red: finalRed, green: finalGreen, blue: finalBlue, alpha: finalAlpha)
}))
}
You can even check the result of this function in use in this demo: https://www.youtube.com/watch?v=ZIz8Bn0-hUA&feature=youtu.be
I decided to write here a short nice solution, but if you need more details, check this question: SKAction.colorizeWithColor makes SKLabelNode disappear
Upvotes: 4
Reputation: 443
SKLabelNode also has a fontColor property that you can set. However, it does not respond to the colorizeWithColor method.
Yet, you can still get it to dynamically change the color of the text by syncing it with another SKSpriteNode color. If you call colorizeWithColor on your sprite, the font color changes with it. And that includes color transitions over the specified duration. Example:
[_tileCountLabel runAction:[SKAction repeatActionForever:
[SKAction customActionWithDuration:COLOR_TRANSITION_SPEED actionBlock:^(SKNode *node, CGFloat elapsedTime) {
_tileCountLabel.fontColor = _tileLayer0.color;
}]]];
Also, I tried using SKCropNode mask to try setting the font color through a parent SKSpriteNode. The colorizeWithColor method on the SKSpriteNode worked, but the font was badly mangled and chunky. So, not useful.
Upvotes: 3
Reputation: 1033
If you want to colorize an SKLabelNode, you could try using the label as a mask and colorizing the background:
SKSpriteNode *background = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(200.0, 200.0)];
SKAction *turnRed = [SKAction colorizeWithColor:[UIColor redColor] colorBlendFactor:1.0 duration:2.0];
SKCropNode *cropNode = [SKCropNode node];
cropNode.maskNode = [yourAwesomeLabel copy];
[cropNode addChild:background];
[background runAction:turnRed];
[self addChild:cropNode];
Upvotes: 2
Reputation: 16308
So here is the SKTexture/SKSpriteNode workaround solution. It could maybe be wrapped in its own class for ease of use. And the one thing to remember is to render this where self.view is not nil...
SKLabelNode *labNode = [SKLabelNode labelNodeWithFontNamed:FONT_GAME];
labNode.fontSize = 30.0f;
labNode.fontColor = [SKColor whiteColor];
labNode.text = @"TEST";
SKTexture *texture;
NSAssert(self.view != nil, @"Can't access self.view so sorry.");
texture = [self.view textureFromNode:labNode];
DLog(@"texture: %@", texture);
if (texture != nil) {
texture.filteringMode = SKTextureFilteringNearest;
SKSpriteNode *spriteText = [SKSpriteNode spriteNodeWithTexture:texture];
DLog(@"spriteText.size: %@", NSStringFromSize(spriteText.size));
spriteText.anchorPoint = ccp(0, 0.5);
spriteText.position = ccp(0, 25);
[self addChild:spriteText];
[spriteText runAction:[SKAction repeatActionForever:[SKAction sequence:@[
[SKAction colorizeWithColor:SKColor.yellowColor colorBlendFactor:1 duration:1],
[SKAction colorizeWithColor:SKColor.yellowColor colorBlendFactor:0 duration:1],
]]]];
}
else {
DLog(@"Texture is nil!");
}
Upvotes: 2