Does anyone know how to bring progressive darkness on a SKScene using SpriteKit?
I tried using a SKLightNode, which works great to have "full" darkness in the scene and some light sources.
I also tried to have a Node in front of everything else where I adjust the alpha to get darker and darker. which works great if there is on light source
But the 2 solutions doesn't work together.
In my example, the blue bar on the buttom control the alpha of the "darkness" node (left = 0 so fully transparent, right = 1 so fully dark), and the white part on the buttom left is to swift on and off the light.
My goal would be to use the bar on the buttom to go from light on to light off, with a gradual transition.
class GameScene: SKScene {
override func didMove(to view: SKView) {
let background = SKSpriteNode(color: .lightGray, size: view.frame.size) //imageNamed: "background")
background.zPosition = 1
background.position = CGPoint(x: view.frame.midX, y: view.frame.midY)
background.lightingBitMask = 0b0001
addChild(background)
let character = SKSpriteNode(color: .blue, size: CGSize(width: 100, height: 100))//imageNamed: "character")
character.zPosition = 2
character.position = CGPoint(x: view.frame.midX, y: view.frame.midY)
character.lightingBitMask = 0b0001
character.shadowCastBitMask = 0b0001
addChild(character)
let lightNode = SKLightNode()
lightNode.name = "SKLightNode"
lightNode.position = CGPoint(x: view.frame.midX, y: view.frame.midY)
lightNode.categoryBitMask = 0b0001
lightNode.lightColor = .white
//lightNode.ambientColor = .white
lightNode.isEnabled = false
addChild(lightNode)
// Control
let elementSize: CGFloat = 40
let lightToggleSize = CGSize(width: elementSize, height: elementSize)
let lightToggle = SKSpriteNode(color: .white, size: lightToggleSize)
lightToggle.name = "LightToggle"
lightToggle.zPosition = 10000
lightToggle.position = CGPoint(x: view.frame.width - (elementSize / 2), y: elementSize / 2)
addChild(lightToggle)
let sideBarSize = CGSize(width: view.frame.width - elementSize, height: elementSize)
let sideBar = SKSpriteNode(color: .blue, size: sideBarSize)
sideBar.name = "SideBar"
sideBar.position = CGPoint(x:(view.frame.width - elementSize) / 2, y: elementSize / 2)
sideBar.zPosition = lightToggle.zPosition
addChild(sideBar)
let darknessNodeSize = CGSize(width: view.frame.width , height: view.frame.height)
let darknessNode = SKSpriteNode(color: .black, size: darknessNodeSize)
darknessNode.name = "DarknessNode"
darknessNode.position = CGPoint(x: view.frame.width / 2, y: view.frame.height / 2)
darknessNode.alpha = 0
darknessNode.zPosition = lightToggle.zPosition - 1
addChild(darknessNode)
}
func handleTouches(_ point: CGPoint) {
let darknessNode = childNode(withName: "DarknessNode") as! SKSpriteNode
let lightNode = childNode(withName: "SKLightNode") as! SKLightNode
let sideBar = childNode(withName: "SideBar")!
let lightToggle = childNode(withName: "LightToggle") as! SKSpriteNode
if lightToggle.contains(point) {
lightNode.isEnabled = !lightNode.isEnabled
lightNode.position = CGPoint(x: lightNode.position.x + 1, y: lightNode.position.y)
} else if sideBar.contains(point) {
darknessNode.alpha = point.x / sideBar.frame.width
} else {
lightNode.position = point
}
}
override func touchesBegan(_ touches: Set<UITouch>,
with event: UIEvent?) {}
override func touchesMoved(_ touches: Set<UITouch>,
with event: UIEvent?) {
handleTouches(touches.first?.location(in: self))
}
override func touchesEnded(_ touches: Set<UITouch>,
with event: UIEvent?) {
handleTouches(touches.first?.location(in: self))
}
}