しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

【Swift】SKLightNodeで画面を明るく照らしてみる

ゲームフレームワークであるSpriteKitのSKLightNodeを使って、画面にライトを追加してみました。

まずは新規プロジェクト作成からゲームを選択します。

f:id:llcc:20170806233459p:plain

プロジェクトを作成したら、GameViewController.swiftを以下のようにします。
サンプルコードを削除して、画面に何も表示されないようにしました。

import UIKit
import SpriteKit
import GameplayKit

class GameViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if let view = self.view as! SKView? {
            let scene = GameScene(size: view.bounds.size)
            scene.scaleMode = .aspectFill
            view.presentScene(scene)
            
            view.ignoresSiblingOrder = true
            
            view.showsFPS = true
            view.showsNodeCount = true
        }
    }
    
    override var prefersStatusBarHidden: Bool {
        return true
    }
}

続けてGameScene.swiftを以下のように修正します。

import SpriteKit
import GameplayKit

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
    }
}

アプリを立ち上げると、下のように真っ白な表示になるかと思います。

f:id:llcc:20170806233733p:plain

続けて画面にSKLightNodeを追加します。

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
        
        let light = SKLightNode()
        light.position = view.center
        light.categoryBitMask = 1
        addChild(light)
        baseNode.lightingBitMask = 1
    }
}

起動すると、中心が光に照らされています。

f:id:llcc:20170806234301p:plain

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
        
        let light = SKLightNode()
        light.position = view.center
        light.categoryBitMask = 1
        addChild(light)
        baseNode.lightingBitMask = 1
    }
}

ライトのfalloffプロパティーを変更すると、光の届く距離が代わります。
試しにデフォルトの1から0.1に変更したら、より遠くまで光が届くようになりました。

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
        
        let light = SKLightNode()
        light.position = view.center
        light.categoryBitMask = 1
        light.falloff = 0.1 // ここを修正
        addChild(light)
        baseNode.lightingBitMask = 1
    }
}

f:id:llcc:20170806234509p:plain

ライトの色はlightColorというプロパティーで変更できます。
ライトがない箇所の色はambientColorというプロパティーで変更します。

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
        
        let light = SKLightNode()
        light.position = view.center
        light.categoryBitMask = 1
        light.lightColor = .blue
        light.ambientColor = .red
        addChild(light)
        baseNode.lightingBitMask = 1
    }
}

lightColorを青、ambientColorを赤にしたら以下のようになりました。

f:id:llcc:20170806234855p:plain

shadowCastBitMaskを使うと光を遮る事ができます。

import SpriteKit
import GameplayKit

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
        
        let light = SKLightNode()
        light.position = view.center
        light.categoryBitMask = 1
        addChild(light)
        baseNode.lightingBitMask = 1
        
        let node = SKSpriteNode(color: .darkGray, size: CGSize(width: 100, height: 100))
        node.position = CGPoint(x: view.frame.width / 2, y: view.frame.height / 2 - 100)
        node.shadowCastBitMask = 1
        addChild(node)
    }
}

f:id:llcc:20170806235615p:plain

この時の影の色はSKLightNodeshadowColorというプロパティーで変更できます。

import SpriteKit
import GameplayKit

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?
    
    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(color: .white, size: view.frame.size)
        baseNode.position = view.center
        baseNode.zPosition = -1
        addChild(baseNode)
        
        let light = SKLightNode()
        light.position = view.center
        light.categoryBitMask = 1
        light.shadowColor = .green
        addChild(light)
        baseNode.lightingBitMask = 1
        
        let node = SKSpriteNode(color: .darkGray, size: CGSize(width: 100, height: 100))
        node.position = CGPoint(x: view.frame.width / 2, y: view.frame.height / 2 - 100)
        node.shadowCastBitMask = 1
        addChild(node)
    }
}

f:id:llcc:20170806235709p:plain