iPhoneコンテナ船

コンテナを運ぶ船を表示するiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createPort()

        createShip()

        createContainers()

        createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.backgroundColor = UIColor(hue: 0.5, saturation: 0.1, brightness: 1, alpha: 1)

        sv.scene = SCNScene()

        sv.allowsCameraControl = true

        sv.autoenablesDefaultLighting = true

        view.addSubview(sv)

        

        self.sceneView = sv

    }

    

    func createPort() {

        for i in 01 {

            let port = SCNBox(width: 10, height: 5, length: 5, chamferRadius: 0)

            port.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.8, brightness: 0.6, alpha: 1)

            let portNode = SCNNode(geometry: port)

            portNode.position = SCNVector3(x: i==0 ? –15 : 15, y: –5, z: 0)

            self.sceneView?.scene?.rootNode.addChildNode(portNode)

            portNode.physicsBody = SCNPhysicsBody.staticBody()

        }

        

        let sea = SCNBox(width: 40, height: 2, length: 40, chamferRadius: 0)

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

        let seaNode = SCNNode(geometry: sea)

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

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

        

        seaNode.runAction(SCNAction.repeatActionForever(SCNAction.sequence([SCNAction.moveByX(0, y: –0.5, z: 0, duration: 2), SCNAction.moveByX(0, y: 0.5, z: 0, duration: 2)])))

    }

    

    func createShip() {

        let ship = SCNCone(topRadius: 8, bottomRadius: 6.5, height: 2)

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

        let shipNode = SCNNode(geometry: ship)

        shipNode.name = “ship”

        shipNode.scale = SCNVector3(x: 1, y: 1, z: 0.3)

        shipNode.position = SCNVector3(x: –10, y: –5, z: 6)

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

    }

    

    func createContainers() {

        for i in 08 {

            let x = (i % 3) * 217

            let y = (i / 3) * 22

            let box = SCNBox(width: 2, height: 2, length: 2, chamferRadius: 0.1)

            box.firstMaterial?.diffuse.contents = UIColor(hue: 0.1 * CGFloat(i), saturation: 0.4, brightness: 0.9, alpha: 1)

            let boxNode = SCNNode(geometry: box)

            boxNode.name = “container \(i)”

            boxNode.position = SCNVector3(x: Float(x), y: Float(y), z: 0)

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

        }

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

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

    }

    var count = 0

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        

        var containerOn = {() -> Void in

            self.sceneView?.scene?.rootNode.childNodes

                .filter { ($0 as! SCNNode).name?.componentsSeparatedByString(” “)[0] == “container” }

                .reduce(0) { (cnt, n) -> Int in

                    let x = Float(cnt % 5) * 215

                    let y = Float(cnt / 5) * 22.9

                    n.runAction(SCNAction.moveTo(SCNVector3(x: Float(x), y: Float(y), z: 6), duration: 0.5), completionHandler: { () -> Void in

                        if let ship = self.sceneView?.scene?.rootNode.childNodeWithName(“ship”, recursively: false) {

                            ship.addChildNode(n as! SCNNode)

                            (n as! SCNNode).position = ship.convertPosition(n.position, fromNode: self.sceneView?.scene?.rootNode)

                        }

                    })

                    return cnt+1

                }

        };

        

        var moveShip = {() -> Void in

            if let ship = self.sceneView?.scene?.rootNode.childNodeWithName(“ship”, recursively: false) {

                ship.runAction(SCNAction.moveByX(20, y: 0, z: 0, duration: 5.0))

            }

        };

        

        

        if count == 0 {

            containerOn();

        }

        else if count == 1 {

            moveShip();

        }

        ++count

    }

}