iOS 8检测SKLightNode是否点亮SKSpriteNode

时间:2015-06-10 16:30:52

标签: ios swift skspritenode sklightnode

我的场景中有几个精灵节点正在投射阴影。我也有一个阴影中的精灵。我希望能够判断用户是否将一个精灵从阴影中移入灯光中。无论如何要快速做到这一点?感谢。

1 个答案:

答案 0 :(得分:0)

不幸的是,这个功能仍未包含在SpriteKit中,但是可以通过一些注意事项实现一个不错的解决方案。

要确定精灵是否投射阴影,通过执行逻辑AND操作,可以针对灯光的categoryBitMask属性测试其shadowCastBitMask属性。“根据{{​​1}}上定义的shadowColor属性的文档中给出的描述,SpriteKit似乎为照明和物理体计算生成完全相同的遮罩数据:

  

计算光照时,会创建阴影,就像投射光线一样   从光节点的位置出来。如果精灵投下阴影,那么   光线在与精灵的物理体相交时被阻挡。   否则,精灵的纹理用于生成掩码,任何   精灵节点纹理中具有alpha值的像素   非零阻挡光线。

SKLightNode有一个方法SKPhysicsWorld,用于执行此类光线相交测试。这意味着我们可以测试精灵是否被任何具有物理体的精灵所遮蔽。所以我们可以编写这样的方法来扩展enumerateBodies(alongRayStart:end:using:)

SKSpriteNode

我们还可以检索场景中哪些灯光照亮特定的精灵:

func isLit(by light: SKLightNode) -> Bool {
    guard light.isEnabled else {
        return false
    }

    var shadowed = false

    scene?.physicsWorld.enumerateBodies(alongRayStart: light.position, end: position) { (body, _, _, stop) in
        if let sprite = body.node as? SKSpriteNode, light.categoryBitMask & sprite.shadowCastBitMask != 0 {
            shadowed = true

            stop.pointee = true
        }
    }

    if shadowed {
        return false
    } else {
        return true
    }
}

如果SpriteKit提供了一种方法来检索这些信息而不将其耦合到物理API,或者要求开发人员推出他们自己的光线投射实现,那就太棒了。