首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS 8检测SKSpriteNode是否由SKLightNode点亮

iOS 8检测SKSpriteNode是否由SKLightNode点亮
EN

Stack Overflow用户
提问于 2015-06-11 00:30:52
回答 1查看 153关注 0票数 2

我的场景中有几个投射阴影的精灵节点。我还有一个在阴影中的精灵。我希望能够判断用户是否将精灵从阴影中移入光线中。不管怎么说,要在swift中做到这一点?谢谢。

EN

回答 1

Stack Overflow用户

发布于 2017-08-05 13:39:33

不幸的是,这个功能仍然没有包含在SpriteKit中,但是可以通过一些警告来实现一个不错的解决方案。

为了确定精灵是否投射阴影,“通过执行逻辑与运算,针对灯光的categoryBitMask属性测试其shadowCastBitMask属性”。根据在SKLightNode上定义的shadowColor属性的文档中的描述,SpriteKit似乎会为光照和物理体计算生成完全相同的掩膜数据

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

SKPhysicsWorld有一个名为enumerateBodies(alongRayStart:end:using:)的方法,用于高效地执行这种光线相交测试。这意味着我们可以测试一个精灵是否被任何具有物理实体的精灵所遮挡。所以我们可以像这样编写一个方法来扩展SKSpriteNode

代码语言:javascript
复制
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
    }
}

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

代码语言:javascript
复制
func lights(affecting sprite: SKSpriteNode) -> [SKLightNode] {
    let lights = sprite.scene?.children.flatMap { (node) -> SKLightNode? in
        node as? SKLightNode
    } ?? []

    return lights.filter { (light) -> Bool in
        sprite.isLit(by: light)
    }
}

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30762191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档