我的场景中有几个投射阴影的精灵节点。我还有一个在阴影中的精灵。我希望能够判断用户是否将精灵从阴影中移入光线中。不管怎么说,要在swift中做到这一点?谢谢。
发布于 2017-08-05 13:39:33
不幸的是,这个功能仍然没有包含在SpriteKit中,但是可以通过一些警告来实现一个不错的解决方案。
为了确定精灵是否投射阴影,“通过执行逻辑与运算,针对灯光的categoryBitMask属性测试其shadowCastBitMask属性”。根据在SKLightNode上定义的shadowColor属性的文档中的描述,SpriteKit似乎会为光照和物理体计算生成完全相同的掩膜数据
计算照明时,会创建阴影,就像光线从灯光节点的位置投射出来一样。如果精灵投射阴影,则光线在与精灵的物理体相交时会被阻挡。否则,精灵的纹理用于生成遮罩,并且精灵节点的纹理中具有非零alpha值的任何像素都会阻挡灯光。
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
}
}我们还可以检索场景中的哪些灯光正在照亮特定的精灵:
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,或者要求开发人员滚动他们自己的光线投射实现,那就太好了。
https://stackoverflow.com/questions/30762191
复制相似问题