2015-10-26 16 views
0

你好开发伙伴如何在sprite套件中缓慢转换颜色?

我试图在SpriteKit中慢慢地改变一个圆的颜色,从原始颜色到新颜色之间有一段时间的过渡,从一种颜色过渡到另一种颜色。我遇到的问题是我的代码不会慢慢地改变,它只是改变,就好像我直接分配了新的颜色。这是我的实际代码:

func changeColor(c: UIColor) { 
     var r:CGFloat = 0 
     var g:CGFloat = 0 
     var b:CGFloat = 0 
     var a:CGFloat = 0 
     c.getRed(&r, green: &g, blue: &b, alpha: &a) 

     var r1:CGFloat = 0 
     var g1:CGFloat = 0 
     var b1:CGFloat = 0 
     var a1:CGFloat = 0 
     circle.fillColor.getRed(&r1, green: &g1, blue: &b1, alpha: &a1); 
     let wait = SKAction.waitForDuration(0.4) 
     r = (r - r1)/10 
     g = (g - g1)/10 
     b = (b - b1)/10 

     for(var i = 0; i < 10; i++) { 
      let cN = UIColor(red: (r1 + r*CGFloat(i)), green: (g1 + g*CGFloat(i)), blue: (b1 + b*CGFloat(i)), alpha: 1.0) 
      circle.fillColor = cN 
      circle.strokeColor = cN 
      runAction(wait) 
     } 
    } 

我真的相信问题出在“runAction(wait)”,但我不确定。我想知道是否有一个默认功能可以做我想做的事,但我非常怀疑它。

回答

4

问题是,您正在试图在for循环中执行所有“live”操作。您的功能中的所有代码在动画的帧之间运行,这样就不起作用。

为了使这个更清晰,让我们暂时忽略wait部分。当你运行一个函数,看起来像这样:

func changeColor() { // unrolled loop and pseudocode colors for clarity 
    circle.fillColor = blue 
    circle.fillColor = red 
    circle.fillColor = green 
} 

... SpriteKit 确实更改圆的颜色三次,立即,但不拉丝的结果。无论您将其设置为最新的颜色只有在所有代码运行完毕并且SpriteKit绘制屏幕后才会显示。

当您使用SKAction S,你在做什么是排队指令SpriteKit遵循随着时间的推移,其中包括对需要多个动画帧任务的说明。但代码中的非SKAction调用仍然与以前相同 - 它们会立即进行更改,在下一帧绘制时您会看到最终结果。

所以,当你的代码看起来是这样的:

func changeColor() { // unrolled loop and pseudocode colors for clarity 
    circle.fillColor = blue 
    circle.runAction(SKAction.waitForDuration(0.4)) 
    circle.fillColor = red 
} 

...事件的顺序是这样的:

  1. 设置颜色为蓝色
  2. 添加等待行动的计划动作列表
  3. 设置颜色为红色
  4. 绘制下一帧(颜色为红色)
  5. 执行计划的行动清单(等待0.4秒执行中的下一个动作之前)

所以,要做的第一件事情是让你的颜色变化停下来是帧间的变化,并把它们添加到超时任务列表 - 即通过SKAction更改颜色。有一个colorizeWithColor动作,但我不确定它是否适用于形状节点(使用它们的单独填充/笔触颜色)。尝试一下,如果失败,您可以尝试runBlock 操作,直接设置fillColor/strokeColor

返回伪代码来讨论排序问题,虽然...

func changeColor() { // unrolled loop and pseudocode color actions 
    circle.runAction(mySetBlueColorAction) 
    circle.runAction(SKAction.waitForDuration(0.4)) 
    circle.runAction(mySetRedColorAction) 
} 

如果你运行这个,你会发现这里仍然存在问题。只需拨打runAction单独行动(大致)并行。所以你的圈子还在两次改变颜色,但是两个变化都在同一时间发生。 (哪一个胜利?我不确定有一个确定的答案。)同时,当你的圈子对它的颜色感到困惑时,它也开始等待0.4秒......究竟是什么?

一个waitForDuration行动才有意义,在上下文中的sequence行动,它是有意义的,有需要的东西后,按顺序等待

所以,如果你希望发生的事情听起来像这个顺序是什么:

  1. 设置颜色
  2. 等一等
  3. 颜色设置为别的

...那么你需要的是一个序列动作描述你想要按顺序发生的事情:

let sequence = SKAction.sequence([ 
    mySetBlueColorAction, 
    SKAction.waitForDuration(0.4), 
    mySetRedColorAction, 
    SKAction.waitForDuration(0.4), 
    mySetGreenColorAction, 
    // etc. 
]) 
+0

谢谢你们长期以来精心构思的解说大师,明天我会尝试你的建议,我会让你知道结果 – Adri