iPhone ハーフパイプ

ハーフパイプをボールがくる~っ、ぴょんというiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        self.setupScene()

        self.createHalfPipe()

        self.createCamera()

    }

    

    func setupScene() {

        let sv = SCNView(frame: self.view.bounds)

        sv.scene = SCNScene()

        sv.scene?.physicsWorld.speed = 5.0;

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

        sv.autoenablesDefaultLighting = true

        self.view.addSubview(sv)

        

        self.sceneView = sv

    }

    func createHalfPipe() {

        

        let r1 = CGFloat(10.0)

        let r2 = CGFloat(8.0)

        

        let path = UIBezierPath()

        path.moveToPoint(CGPoint(x: r1, y: 0))

        for i in 0..<200 {

            let angle = Double(i % 100) * M_PI / 100.0

            if (i / 100) == 0 {

                path.addLineToPoint(CGPoint(x: r1 * CGFloat(cos(angle)), y: r1 * CGFloat(sin(angle))))

            } else {

                path.addLineToPoint(CGPoint(x: r2 * CGFloat(cos(angle)), y: r2 * CGFloat(sin(angle))))

            }

        }

        

        let halfpipe = SCNShape(path: path, extrusionDepth: 50)

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

        halfpipe.firstMaterial?.specular.contents = UIColor.whiteColor()

        let halfpipeNode = SCNNode(geometry: halfpipe)

        halfpipeNode.transform = SCNMatrix4MakeRotation(Float(M_PI) + 0.1, 1, 0, 0)

        halfpipeNode.transform = SCNMatrix4Rotate(halfpipeNode.transform, Float(M_PI)/10.0, 0, 1, 0)

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

        

        halfpipeNode.physicsBody = SCNPhysicsBody.staticBody()

        halfpipeNode.physicsBody?.physicsShape = SCNPhysicsShape(geometry: halfpipe, options: [SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron])

    }

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

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

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

    }

    

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

        let p = touches.anyObject()!.locationInView(self.sceneView)

        

        // zNear: 1.0, zFar: 100.0

        let v = self.sceneView!.unprojectPoint(SCNVector3(x: Float(p.x), y: Float(p.y), z: 0.99))

        

        let ball = SCNSphere(radius: 2)

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

        ball.firstMaterial?.specular.contents = UIColor(hue: 0.2, saturation: 0.1, brightness: 1, alpha: 1)

        

        let ballNode = SCNNode(geometry: ball)

        ballNode.position = SCNVector3(x: v.x, y: 40, z: –1)

        ballNode.physicsBody = SCNPhysicsBody.dynamicBody()

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

    }

}