SKShapeNode – animation颜色的变化

我正在使用SpriteKit进行游戏。 我正在用SKShapeNode绘制一个形状。 现在我想animation它的颜色变化,但SKActions不适用于SKShapeNode。 有没有办法做到这一点,或者我必须使用不同的方法?

谢谢。

编辑:

感谢LearnCocos2D,我能够想出这个快速(而且完全不完美)的解决scheme。

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]]; }]; 

我只需要淡化两个特定的颜色,所以它不是一个通用的解决scheme,但现在已经足够了。

谢谢

使用customActionWithDuration:block:并更改fillColorstrokeColor属性。

我猜想着色操作不起作用,因为SKShapeNode没有color属性。 值得尝试将这个属性添加到子类或类别中的类中,并将其redirect到fillColorstrokeColor或两者。

我发现Paddy Collins在下面回答是有帮助的,所以我把它写到了Swift上来。

 // In the class that calls colorTransitionAction // Include these variables // In my code its the class that aggregates the sprite var frgba = [CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0)] var trgba = [CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0)] func lerp(a : CGFloat, b : CGFloat, fraction : CGFloat) -> CGFloat { return (ba) * fraction + a } func colorTransitionAction(fromColor : UIColor, toColor : UIColor, duration : Double = 0.4) -> SKAction { fromColor.getRed(&frgba[0], green: &frgba[1], blue: &frgba[2], alpha: &frgba[3]) toColor.getRed(&trgba[0], green: &trgba[1], blue: &trgba[2], alpha: &trgba[3]) return SKAction.customAction(withDuration: duration, actionBlock: { (node : SKNode!, elapsedTime : CGFloat) -> Void in let fraction = CGFloat(elapsedTime / CGFloat(duration)) let transColor = UIColor(red: lerp(self.frgba[0], b: self.trgba[0], fraction: fraction), green: lerp(self.frgba[1], b: self.trgba[1], fraction: fraction), blue: lerp(self.frgba[2], b: self.trgba[2], fraction: fraction), alpha: lerp(self.frgba[3], b: self.trgba[3], fraction: fraction)) (node as! SKShapeNode).fillColor = transColor } ) } 

这是我的实现。 我觉得更容易阅读。

 -(SKAction*)getColorFadeActionFrom:(SKColor*)col1 toColor:(SKColor*)col2 { // get the Color components of col1 and col2 CGFloat r1 = 0.0, g1 = 0.0, b1 = 0.0, a1 =0.0; CGFloat r2 = 0.0, g2 = 0.0, b2 = 0.0, a2 =0.0; [col1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1]; [col2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2]; // return a color fading on the fill color CGFloat timeToRun = 0.3; return [SKAction customActionWithDuration:timeToRun actionBlock:^(SKNode *node, CGFloat elapsedTime) { CGFloat fraction = elapsedTime / timeToRun; SKColor *col3 = [SKColor colorWithRed:lerp(r1,r2,fraction) green:lerp(g1,g2,fraction) blue:lerp(b1,b2,fraction) alpha:lerp(a1,a2,fraction)]; [(SKShapeNode*)node setFillColor:col3]; [(SKShapeNode*)node setStrokeColor:col3]; }]; } double lerp(double a, double b, double fraction) { return (ba)*fraction + a; } 

我想要在我的多边形上连续跳动的光芒。 我使用runBlock:而不是customActionWithDuration:block:但是可以无限地运行那个。

 SKShapeNode *shape = [SKShapeNode shapeNodeWithPoints:points count:indices.count]; shape.fillColor = [[SKColor yellowColor] colorWithAlphaComponent:0.2]; shape.strokeColor = [SKColor clearColor]; [self addChild:shape]; shape.userData = @{@"minAlpha": @0, @"maxAlpha": @0.5, @"deltaAlpha": @.025}.mutableCopy; SKAction *a = [SKAction runBlock:^{ SKColor *color = shape.fillColor; CGFloat delta = [shape.userData[@"deltaAlpha"] floatValue]; CGFloat w, alpha; [color getWhite:&w alpha:&alpha]; shape.fillColor = [color colorWithAlphaComponent:alpha + delta]; if ((delta < 0 && alpha <= [shape.userData[@"minAlpha"] floatValue]) || (delta > 0 && alpha >= [shape.userData[@"maxAlpha"] floatValue])) { shape.userData[@"deltaAlpha"] = @(-delta); } }]; SKAction *slice = [SKAction sequence:@[a, [SKAction waitForDuration:0.05]]]; SKAction *glow = [SKAction repeatActionForever:slice]; [shape runAction:glow]; 

我发现上面的GOR的答案是有帮助的,他发现Paddy Collin的答案在上面很有帮助,所以我通过一系列的颜色将其扩展为animation。

 extension SKAction { func multipleColorTransitionAction(colors:[SKColor], duration:Double) -> SKAction { guard colors.count > 1 else { return SKAction.colorize(withColorBlendFactor: 1, duration: 0) } var colorActions:[SKAction] = [] for i in 1..<colors.count { colorActions.append( colorTransitionAction(fromColor: colors[i-1] , toColor: colors[i], duration: duration/Double(colors.count)) ) } colorActions.append(colorTransitionAction(fromColor: colors.last!, toColor: colors.first!, duration: duration/Double(colors.count))) return SKAction.sequence(colorActions) } func colorTransitionAction(fromColor : SKColor, toColor : SKColor, duration : Double = 0.4) -> SKAction { func lerp(_ a : CGFloat, b : CGFloat, fraction : CGFloat) -> CGFloat { return (ba) * fraction + a } var frgba:[CGFloat] = [0,0,0,0] var trgba:[CGFloat] = [0,0,0,0] fromColor.getRed(&frgba[0], green: &frgba[1], blue: &frgba[2], alpha: &frgba[3]) toColor.getRed(&trgba[0], green: &trgba[1], blue: &trgba[2], alpha: &trgba[3]) return SKAction.customAction(withDuration: duration, actionBlock: { (node : SKNode!, elapsedTime : CGFloat) -> Void in let fraction = CGFloat(elapsedTime / CGFloat(duration)) let transColor = UIColor(red: lerp(frgba[0], b: trgba[0], fraction: fraction), green: lerp(frgba[1], b: trgba[1], fraction: fraction), blue: lerp(frgba[2], b: trgba[2], fraction: fraction), alpha: lerp(frgba[3], b: trgba[3], fraction: fraction)) (node as! SKShapeNode).fillColor = transColor }) } } 

我改变了一些关于GOR的原始function,以适应多种颜色,主要封装frgbatrgbalerp所以块不需要引用self ,并允许frgbatrgba有多个块捕获多个实例。 以下是一个示例用法:

 let theRainbow:[SKColor] = [.red,.orange,.yellow,.green,.cyan,.blue,.purple,.magenta] let rainbowSequenceAction = SKAction.multipleColorTransitionAction(colors: theRainbow, duration: 10) star.run(SKAction.repeatForever(rainbowSequenceAction)) 

starSKShapeNode