iPhone手品ハット

ステッキで帽子を叩くとボールが飛び出すiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createHat()

        createStick()

        createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.backgroundColor = UIColor(hue: 0.25, saturation: 0.8, brightness: 0.3, alpha: 1)

        sv.scene = SCNScene()

        sv.autoenablesDefaultLighting = true

        view.addSubview(sv)

        

        sceneView = sv

    }

    

    func createHat() {

        let hat = SCNNode()

        hat.name = “hat”

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

        

        let side = SCNTube(innerRadius: 1.9, outerRadius: 2.0, height: 4)

        side.firstMaterial?.diffuse.contents = UIColor(white: 0.15, alpha: 1)

        let sideNode = SCNNode(geometry: side)

        hat.addChildNode(sideNode)

        

        let belt = SCNTube(innerRadius: 1.95, outerRadius: 2.01, height: 1)

        belt.firstMaterial?.diffuse.contents = UIColor(hue: 0, saturation: 0.9, brightness: 0.7, alpha: 1)

        let beltNode = SCNNode(geometry: belt)

        beltNode.position = SCNVector3(x: 0, y: 1.5, z: 0)

        hat.addChildNode(beltNode)

        

        let brim = SCNTube(innerRadius: 1.95, outerRadius: 3.0, height: 0.1)

        brim.firstMaterial?.diffuse.contents = UIColor(white: 0.15, alpha: 1)

        let brimNode = SCNNode(geometry: brim)

        brimNode.position = SCNVector3(x: 0, y: 2.05, z: 0)

        hat.addChildNode(brimNode)

    }

    

    func createStick() {

        let stick = SCNNode()

        stick.name = “stick”

        stick.pivot = SCNMatrix4MakeTranslation(0, –2, 0)

        stick.position = SCNVector3(x: 5, y: 3, z: 0)

        let white = SCNBox(width: 0.4, height: 2, length: 0.4, chamferRadius: 0.2)

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

        let whiteNode = SCNNode(geometry: white)

        whiteNode.position = SCNVector3(x: 0, y: 1, z: 0)

        stick.addChildNode(whiteNode)

        

        let black = SCNBox(width: 0.4, height: 4, length: 0.4, chamferRadius: 0.2)

        black.firstMaterial?.diffuse.contents = UIColor(white: 0.1, alpha: 1)

        let blackNode = SCNNode(geometry: black)

        blackNode.position = SCNVector3(x: 0, y: –1.8, z: 0)

        stick.addChildNode(blackNode)

        

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

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

        camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: –0.1)

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

    }

    

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

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

        stick?.runAction(SCNAction.sequence([SCNAction.rotateToX(0, y: 0, z: CGFloat(M_PI) * 0.55, duration: 0.3), SCNAction.waitForDuration(0.4), SCNAction.rotateToX(0, y: 0, z: 0, duration: 0.2)]))

        

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.7 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {

            let ball = SCNSphere(radius: 0.5)

            ball.firstMaterial?.diffuse.contents = UIColor.yellowColor()

            let ballNode = SCNNode(geometry: ball)

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

            

            ballNode.physicsBody = SCNPhysicsBody.dynamicBody()

            ballNode.physicsBody?.applyForce(SCNVector3(x: –2.5, y: 15, z: 0), impulse: true)

            

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(3 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {

                ballNode.removeFromParentNode()

            })

        })

    }

}