iPhone箱庭 昼と夜

昼と夜でくるっと回る箱庭みたいなiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createStage()

        createCover()

        createCamera()

    }

    

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.scene = SCNScene()

        sv.backgroundColor = UIColor.lightGrayColor()

        view.addSubview(sv)

        

        sceneView = sv

    }

    func createStage() {

        let stage = SCNCylinder(radius: 10, height: 1)

        stage.firstMaterial?.diffuse.contents = UIColor.brownColor()

        let stageNode = SCNNode(geometry: stage)

        stageNode.name = “stage”

        sceneView?.scene?.rootNode.addChildNode(stageNode)

        

        // day

        let halfCircle = UIBezierPath(arcCenter: CGPointZero, radius: 10, startAngle: 0, endAngle: CGFloat(M_PI), clockwise: true)

        halfCircle.flatness = 0.1

        let day = SCNShape(path: halfCircle, extrusionDepth: 0.1)

        day.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.2, brightness: 1, alpha: 1)

        let dayNode = SCNNode(geometry: day)

        stageNode.addChildNode(dayNode)

        

        // sun

        let sun = SCNSphere(radius: 2)

        sun.firstMaterial?.diffuse.contents = UIColor(hue: 0.02, saturation: 0.5, brightness: 1, alpha: 1)

        let sunNode = SCNNode(geometry: sun)

        sunNode.position = SCNVector3(x: –7, y: 7, z: 0)

        stageNode.addChildNode(sunNode)

        

        // building day

        let building = SCNBox(width: 3, height: 5, length: 1, chamferRadius: 0)

        building.firstMaterial?.diffuse.contents = UIColor(white: 0.8, alpha: 1)

        let buildingNode = SCNNode(geometry: building)

        buildingNode.position = SCNVector3(x: 5, y: 2.5, z: 0)

        stageNode.addChildNode(buildingNode)

        for i in 0..<4 {

            let x = Float(i % 2) * 1.50.8

            let y = Float(i / 2) * 1.5 + 0.2

            let wind = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)

            wind.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.4, brightness: 1, alpha: 1)

            let windNode = SCNNode(geometry: wind)

            windNode.position = SCNVector3(x: x, y: y, z: 0.5)

            buildingNode.addChildNode(windNode)

        }

        

        // night

        halfCircle.applyTransform(CGAffineTransformMakeRotation(CGFloat(M_PI)))

        let night = SCNShape(path: halfCircle, extrusionDepth: 0.1)

        night.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.2, brightness: 0.1, alpha: 1)

        let nightNode = SCNNode(geometry: night)

        stageNode.addChildNode(nightNode)

        

        // moon

        let moon = SCNSphere(radius: 2)

        moon.firstMaterial?.diffuse.contents = UIColor(hue: 0.15, saturation: 0.5, brightness: 0.9, alpha: 1)

        let moonNode = SCNNode(geometry: moon)

        moonNode.position = SCNVector3(x: 7, y: –7, z: 0)

        stageNode.addChildNode(moonNode)

        

        // building night

        let buildingNight = SCNBox(width: 3, height: 5, length: 1, chamferRadius: 0)

        buildingNight.firstMaterial?.diffuse.contents = UIColor(white: 0.5, alpha: 1)

        let buildingNightNode = SCNNode(geometry: buildingNight)

        buildingNightNode.position = SCNVector3(x: –5, y: –2.5, z: 0)

        stageNode.addChildNode(buildingNightNode)

        for i in 0..<4 {

            let x = Float(i % 2) * 1.50.8

            let y = Float(i / 2) * 1.5 + 0.2

            let wind = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)

            wind.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.4, brightness: 0.4, alpha: 1)

            let windNode = SCNNode(geometry: wind)

            windNode.position = SCNVector3(x: -x, y: -y, z: 0.5)

            buildingNightNode.addChildNode(windNode)

        }

    }

    

    func createCover() {

        let tube = SCNTube(innerRadius: 10, outerRadius: 11, height: 10)

        tube.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 0.5, brightness: 0.5, alpha: 1)

        let tubeNode = SCNNode(geometry: tube)

        tubeNode.position = SCNVector3(x: 0, y: –5, z: 0)

        sceneView?.scene?.rootNode.addChildNode(tubeNode)

    }

    

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let n = sceneView?.scene?.rootNode.childNodeWithName(“stage”, recursively: false)

        n?.runAction(SCNAction.rotateByAngle(CGFloat(M_PI), aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 0.5))

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.position = SCNVector3(x: 0, y: 0, z: 40)

        camera.transform = SCNMatrix4Rotate(camera.transform, –0.4, 1, 0, 0)

        sceneView?.scene?.rootNode.addChildNode(camera)

    }

}