iPhoneピンと車

並んだピンを車で倒すiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    weak var mviechle : SCNPhysicsVehicle?

    

    override func viewDidLoad() {

        super.viewDidLoad()

    

        setupScene()

        createBoard()

        createCar()

        createPin()

        createCamera()

    }

    

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

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

        sv.scene = SCNScene()

        sv.preferredFramesPerSecond = 30

        sv.autoenablesDefaultLighting = true

        view.addSubview(sv)

        self.sceneView = sv

    }

    

    func createBoard() {

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

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

        let boardNode = SCNNode(geometry: board)

        boardNode.physicsBody = SCNPhysicsBody.staticBody()

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

        

        let boardFrameNode = SCNNode()

        for i in 0..<4 {

            let boardFrame = SCNBox(width: 120, height: 5, length: 2, chamferRadius: 0)

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

            let boardFrameNode = SCNNode(geometry: boardFrame)

            boardFrameNode.transform = SCNMatrix4Translate(boardFrameNode.transform, 0, 0, 6040 * Float((i % 2)))

            boardFrameNode.transform = SCNMatrix4Rotate(boardFrameNode.transform, Float(M_PI / 2.0) * Float(i), 0, 1, 0)

            boardFrameNode.physicsBody = SCNPhysicsBody.staticBody()

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

        }

    }

    

    func createCar() {

        let v = SCNNode()

        v.position = SCNVector3(x: 0, y: 10, z: 30)

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

        

        let body = SCNBox(width: 1.4, height: 1, length: 4, chamferRadius: 0.01)

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

        let bodyNode = SCNNode(geometry: body)

        v.addChildNode(bodyNode)

        

        var wheels = [SCNPhysicsVehicleWheel]()

        let wp = [SCNVector3(x: 1.2, y: –0.2, z: 1.1), SCNVector3(x: –1.2, y: –0.2, z: 1.1), SCNVector3(x: 1.2, y: –0.2, z: –1.1), SCNVector3(x: –1.2, y: –0.2, z: –1.1)]

        

        for i in 0..<4 {

            let wheel = SCNSphere(radius: 0.4)

            wheel.firstMaterial?.diffuse.contents = UIColor.blackColor()

            let wheelNode = SCNNode(geometry: wheel)

            v.addChildNode(wheelNode)

            

            let w = SCNPhysicsVehicleWheel(node: wheelNode)

            w.axle = SCNVector3(x: 1, y: 0, z: 0)

            w.connectionPosition = wp[i]

            w.suspensionRestLength = 0.01

            w.frictionSlip = 0.6

            wheels.append(w)

            

            

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

            bar.firstMaterial?.diffuse.contents = UIColor.grayColor()

            let barNode = SCNNode(geometry: bar)

            wheelNode.addChildNode(barNode)

        }

        

        v.physicsBody = SCNPhysicsBody.dynamicBody()

        let vehicle = SCNPhysicsVehicle(chassisBody: v.physicsBody, wheels: wheels)

        sceneView?.scene?.physicsWorld.addBehavior(vehicle)

        

        mviechle = vehicle

    }

    

    func createPin() {

        for i in 0..<5 {

            let pin = SCNCylinder(radius: 2, height: 10)

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

            let pinNode = SCNNode(geometry: pin)

            pinNode.position = SCNVector3(x: –8 + 4 * Float(i), y: 6, z: –50 + Float(i%2) * 8)

            pinNode.physicsBody = SCNPhysicsBody.dynamicBody()

            pinNode.physicsBody?.mass = 0.1

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

        }

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.camera?.zFar = 400

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

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

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

    }

    

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

        mviechle?.applyEngineForce(40, forWheelAtIndex: 0)

        mviechle?.applyEngineForce(40, forWheelAtIndex: 1)

        mviechle?.applyEngineForce(40, forWheelAtIndex: 2)

        mviechle?.applyEngineForce(40, forWheelAtIndex: 3)

    }

}