ios - 与转换它的 SKSpriteNode 一起淡化阴影

标签 ios swift sprite-kit shadow sknode

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

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)

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

SKSpriteNode with alpha = 1.0 casting a shadow

现在我通过操纵它的 alpha 值淡化 block ,例如通过运行一个 Action :

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

这是一个尴尬的情况:当 block 变得越来越半透明时,阴影却完全一样。这是 Action 结束前一刻的样子:

enter image description here

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

不过,随着转换它的物体变得越来越透明,让阴影慢慢变得越来越弱会更好

问题:

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

最佳答案

这有点棘手,因为 SKLightNode 转换的阴影不受节点的 alpha 属性的影响。您需要做的是在淡出 block 的同时淡出 SKLightNodeshadowColor 属性的 Alpha channel .

基本步骤是:

  1. 存储灯光的 shadowColor 和该颜色的 alpha channel 以供引用。
  2. 创建一个 SKAction.customActionWithDuration,其中:
    1. 根据原始值和到目前为止操作已经过去了多少时间,重新计算 alpha channel 的值。
    2. 将灯光的 shadowColor 设置为其原始颜色,但使用新的 alpha channel 。
  3. 并行运行 block 的淡入淡出 Action 和阴影的淡入淡出 Action 。

示例:

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]))

关于ios - 与转换它的 SKSpriteNode 一起淡化阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26047010/

相关文章:

swift - 如何在 Swift 中用图像填充表格单元格

ios - 从mapView中删除用户位置注释

ios - UITable 滚动时自动将 UI 元素添加到 UIStackView

ios - 无法从 iOS 将图像上传到 S3

ios - 在 Xcode 中设置自定义类适用于 iOS 9.1 模拟器,但不适用于 iOS 8.4

ios - 如何在 spriteKit swift 中降低 Sprite 的速度?

ios - 在 SpriteKit 中重置场景

ios - Storyboard "show"segue 在更新到 xcode7 后不起作用(仅在一种情况下)

ios - swift:如何将base64String编码的图片保存到本地目录

ios - 在 UITableView 上出队和重新排队时,MKMapView 不断缩小