5

这是我的设置,使用 Sprite Kit。首先,我在 SKScene 中创建一个简单的精灵节点,如下所示:

let block = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(90, 160))
block.zPosition = 2
block.shadowCastBitMask = 1
addChild(block)

然后在场景中添加一个光照节点:

let light = SKLightNode()
light.categoryBitMask = 1
light.falloff = 1
addChild(light)

果然,该块现在投下了一个漂亮的小阴影:

具有 alpha = 1.0 的 SKSpriteNode 投射阴影

现在我通过操作它的 alpha 值来淡化块,例如通过运行一个动作:

let fadeOut = SKAction.fadeAlphaTo(0.0, duration: 5.0)
block.runAction(fadeOut)

这是尴尬的情况:当块变得越来越半透明时,阴影保持不变。这是动作结束前一刻的样子:

在此处输入图像描述

一旦 alpha 完全下降到 0.0,阴影就会从一帧到下一帧突然消失。

然而,随着投射它的物体变得越来越透明,让阴影慢慢变得越来越弱更好

问题:

Sprite Kit 可以实现这样的效果吗?如果是这样,你会怎么做?

4

2 回答 2

3

这有点棘手,因为 an 投射的阴影SKLightNode不受节点alpha属性的影响。您需要做的是shadowColorSKLightNode淡出block.

基本步骤是:

  1. 存储灯光shadowColor和该颜色的 Alpha 通道以供参考。
  2. 创建一个SKAction.customActionWithDuration
    1. 重新计算 Alpha 通道的值,基于原始值以及到目前为止该动作已经过去了多少时间。
    2. 将灯光设置shadowColor为其原始颜色,但使用新的 Alpha 通道。
  3. 并行运行块的淡入淡出动作和阴影的淡入淡出动作。

例子:

let fadeDuration = 5.0 // We're going to use this a lot

// Grab the light's original shadowColor so we can use it later
let shadowColor = light.shadowColor

// Also grab its alpha channel so we don't have to do it each time
let shadowAlpha = CGColorGetAlpha(shadowColor.CGColor)

let fadeShadow = SKAction.customActionWithDuration(fadeDuration) {
    // The first parameter here is the node this is running on.
    // Ideally you'd use that to get the light, but I'm taking
    // a shortcut and accessing it directly.
    (_, time) -> Void in

    // This is the original alpha channel of the shadow, adjusted
    // for how much time has past while running the action so far
    // It will go from shadowAlpha to 0.0 over fadeDuration
    let alpha = shadowAlpha - (shadowAlpha * time / CGFloat(fadeDuration))

    // Set the light's shadowColor to the original color, but replace
    // its alpha channel our newly calculated one
    light.shadowColor = shadowColor.colorWithAlphaComponent(alpha)
}

// Make the action to fade the block too; easy!
let fadeBlock = SKAction.fadeAlphaTo(0.0, duration: fadeDuration)

// Run the fadeBlock action and fadeShadow action in parallel
block.runAction(SKAction.group([fadeBlock, fadeShadow]))
于 2014-09-26T03:18:16.353 回答
1

以下是确保阴影和块淡入/淡出一起的一种方法。要使用这种方法,您需要将 light 和 block 声明为类的属性。

override func didEvaluateActions() {
    light.shadowColor = light.shadowColor.colorWithAlphaComponent(block.alpha/2.0)
}

编辑:这是实现上述内容的方法。

class GameScene: SKScene {

    let light = SKLightNode()
    let block = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(90, 160))

    override func didMoveToView(view: SKView) {

        /* Setup your scene here */
        block.zPosition = 2
        block.shadowCastBitMask = 1
        block.position = CGPointMake(100, 100)

        addChild(block)

        light.categoryBitMask = 1
        light.falloff = 1
        addChild(light)

        let fadeOut = SKAction.fadeAlphaTo(0.0, duration: 5.0);
        let fadeIn = SKAction.fadeAlphaTo(1.0, duration: 5.0);

        block.runAction(SKAction.sequence([fadeOut,fadeIn,fadeOut]))
    }

    override func didEvaluateActions() {
        light.shadowColor = light.shadowColor.colorWithAlphaComponent(block.alpha/2.0)
    }
}
于 2014-09-26T07:53:16.670 回答