iPhone箱積み

パネルをタッチして箱を積んでいくiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var scene : SCNScene?

    weak var selected : SCNNode?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        self.setupScene()

        self.createBox()

        self.createCamera()

        self.createLight()

        

        self.setupButton()

    }

    

    func setupScene() {

        let h = CGRectGetMidY(self.view.bounds)

        var sceneView = SCNView(frame: CGRectMake(0, 0, h, h))

        sceneView.backgroundColor = UIColor(hue: 0.25, saturation: 0.1, brightness: 0.8, alpha: 1)

        sceneView.center = CGPointMake(CGRectGetMidX(self.view.bounds), h/2.0)

        sceneView.scene = SCNScene()

        self.view.addSubview(sceneView)

        

        self.scene = sceneView.scene

    }

    

    func createBox() {

        var table = SCNBox(width: 18, height: 2, length: 18, chamferRadius: 0)

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

        var tableNode = SCNNode(geometry: table)

        tableNode.name = “table”

        self.scene?.rootNode.addChildNode(tableNode)

        

        for i in 19 {

            var box = SCNBox(width: 6, height: 6, length: 6, chamferRadius: 1)

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

            var boxNode = SCNNode(geometry: box)

            boxNode.name = “box”

            let x : Float = Float((i – 1) % 3) * 66.0

            let z : Float = Float((i – 1) / 3) * 66.0

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

            self.scene?.rootNode.addChildNode(boxNode)

        }

    }

    

    func setupButton() {

        self.view.backgroundColor = UIColor(hue: 0.8, saturation: 0.2, brightness: 1, alpha: 1)

        let h = CGRectGetMidY(self.view.bounds)

        let w = CGRectGetMaxX(self.view.bounds)

        for i in 0..<9 {

            let x = CGFloat(i % 3) * w / 3.0

            let y = CGFloat(i / 3) * h / 3.0 + h

            let btn = UIButton.buttonWithType(.System) as UIButton

            btn.titleLabel?.font = UIFont.boldSystemFontOfSize(40)

            btn.frame = CGRectMake(x, y, w/3.0, w/3.0)

            btn.backgroundColor = UIColor(hue: 0.3, saturation: 0.2, brightness: 1, alpha: 1)

            btn.setTitle(\(i + 1), forState: .Normal)

            self.view.addSubview(btn)

            

            btn.addTarget(self, action: “tapButton:”, forControlEvents: .TouchUpInside)

        }

    }

    

    func tapButton(btn : UIButton) {

        var t : NSString? = btn.titleLabel?.text

        var num = t!.intValue1

        var x : Float = Float(num % 3) * 6.06.0

        var z : Float = Float(num / 3) * 6.06.0

        var from = SCNVector3(x: x, y: 100, z: z)

        var to = SCNVector3(x: x, y: –10, z: z)

        

        var hits = self.scene?.rootNode.hitTestWithSegmentFromPoint(from, toPoint: to, options:[SCNHitTestSortResultsKey:true])

        var hit = (hits!.first as SCNHitTestResult).node as SCNNode

        

        if self.selected == nil {

            if hit.name == “box” {

                SCNTransaction.begin()

                SCNTransaction.setAnimationDuration(0.5)

                hit.transform = SCNMatrix4Translate(hit.transform, 0, 8, 0)

                SCNTransaction.commit()

                self.selected = hit

            }

        } else {

            var h : Float = 1.0

            if hit.name == “box” {

                h = hit.position.y + 3.0

            }

            

            SCNTransaction.begin()

            SCNTransaction.setAnimationDuration(0.5)

            self.selected?.transform = SCNMatrix4MakeTranslation(x, h + 8.0, z)

            SCNTransaction.setCompletionBlock({ () -> Void in

                

                SCNTransaction.begin()

                SCNTransaction.setAnimationDuration(0.5)

                self.selected?.transform = SCNMatrix4MakeTranslation(x, h + 3.0, z)

                self.selected = nil

                SCNTransaction.commit()

                

            })

            SCNTransaction.commit()

        }

        

        

        

        

    }

    

    func createCamera() {

        var camera = SCNNode()

        camera.camera = SCNCamera()

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

        self.scene?.rootNode.addChildNode(camera)

    }

    

    func createLight() {

        var light = SCNLight()

        light.type = SCNLightTypeOmni

        var lightNode = SCNNode()

        lightNode.position = SCNVector3(x: 5, y: 10, z: 30)

        self.scene?.rootNode.addChildNode(lightNode)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

}