本文介绍了SKShapeNode - 动画颜色变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SpriteKit 开发游戏.我正在用 SKShapeNode 绘制一个形状.现在我想为其颜色变化设置动画,但 SKActions 不适用于 SKShapeNode.有什么方法可以做到这一点,还是我必须使用不同的方法?

I'm working on a game with SpriteKit. I'm drawing a shape with SKShapeNode. Now I want to animate its colour change but the SKActions is not working for SKShapeNode. Is there any way to do this or I have to use a different approach?

谢谢.

感谢 LearnCocos2D,我能够想出这个快速(但并不完美)的解决方案.

Thanks to LearnCocos2D I was able to come up with this quick (and totally not perfect) solution.

int groundChangeInterval = 5;
SKColor *originalColor = [SKColor colorWithRed:0.92 green:0.87 blue:0.38 alpha:1.0];
SKColor *finalColor = [SKColor colorWithRed:0.29 green:0.89 blue:0.31 alpha:1.0];

CGFloat red1 = 0.0, green1 = 0.0, blue1 = 0.0, alpha1 = 0.0;
[originalColor getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];

CGFloat red2 = 0.0, green2 = 0.0, blue2 = 0.0, alpha2 = 0.0;
[finalColor getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];

SKAction *changeGroundColor = [SKAction customActionWithDuration:groundChangeInterval actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    CGFloat step = elapsedTime/groundChangeInterval;

    CGFloat red3 = 0.0, green3 = 0.0, blue3 = 0.0;
    red3 = red1-(red1-red2)*step;
    green3 = green1-(green1-green2)*step;
    blue3 = blue1-(blue1-blue2)*step;

    [(SKShapeNode*)node setFillColor:[SKColor colorWithRed:red3 green:green3 blue:blue3 alpha:1.0]];
    [(SKShapeNode*)node setStrokeColor:[SKColor colorWithRed:red3 green:green3 blue:blue3 alpha:1.0]];
}];

我只需要淡化两种特定的颜色,所以这不是一个通用的解决方案,但现在已经足够了.

I only needed to fade two specific colours so it is not a universal solution but it is enough for now.

谢谢

推荐答案

已针对 Swift 4.2 更新

这是您需要放入的通用代码和扩展文件或类似的东西.

This the common code that you need to place in and extension file or something of the sort.

func lerp(a : CGFloat, b : CGFloat, fraction : CGFloat) -> CGFloat
{
    return (b-a) * fraction + a
}

struct ColorComponents {
    var red = CGFloat(0)
    var green = CGFloat(0)
    var blue = CGFloat(0)
    var alpha = CGFloat(0)
}

extension UIColor {
    func toComponents() -> ColorComponents {
        var components = ColorComponents()
        getRed(&components.red, green: &components.green, blue: &components.blue, alpha: &components.alpha)
        return components
    }
}

extension SKAction {
    static func colorTransitionAction(fromColor : UIColor, toColor : UIColor, duration : Double = 0.4) -> SKAction
    {
        return SKAction.customAction(withDuration: duration, actionBlock: { (node : SKNode!, elapsedTime : CGFloat) -> Void in
            let fraction = CGFloat(elapsedTime / CGFloat(duration))
            let startColorComponents = fromColor.toComponents()
            let endColorComponents = toColor.toComponents()
            let transColor = UIColor(red: lerp(a: startColorComponents.red, b: endColorComponents.red, fraction: fraction),
                                     green: lerp(a: startColorComponents.green, b: endColorComponents.green, fraction: fraction),
                                     blue: lerp(a: startColorComponents.blue, b: endColorComponents.blue, fraction: fraction),
                                     alpha: lerp(a: startColorComponents.alpha, b: endColorComponents.alpha, fraction: fraction))
            (node as? SKSpriteNode)?.color = transColor
        }
        )
    }
}

用法:

redSKSpriteNodeThatBecomesBlue.run(SKAction.colorTransitionAction(fromColor: .red, toColor: .blue, duration: 5))

请注意,对于 SKShapeNode 或其他目的,您需要重写此行以满足您的需要:

Please note that for SKShapeNode or other purposes you need to rewrite this line to suit your need:

(node as?SKSpriteNode)?.color = transColor

此解决方案最初受到 Paddy Collins 回答的极大启发.

This solution is heavily inspired originally by Paddy Collins answer.

这篇关于SKShapeNode - 动画颜色变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 09:08