iPhoneドミノ2

回転する板をつかって上下のドミノを倒すiPhoneアプリのサンプルコードを書いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var scene : SCNScene?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        self.view.backgroundColor = UIColor(hue: 0.9, saturation: 0.3, brightness: 1, alpha: 1)

        self.setupScene()

        self.createDominos()

        self.createCamera()

    }

    func setupScene() {

        let w = CGRectGetMaxX(self.view.bounds)

        let sv = SCNView(frame: CGRect(x: 0, y: 0, width: w, height: w))

        sv.scene = SCNScene()

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

        

        self.view.addSubview(sv)

        self.scene = sv.scene

    }

    func createDominos() {

        

        // plate

        for i in 0..<2 {

            let line = SCNBox(width: 40, height: 1, length: 4, chamferRadius: 0)

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

            let lineNode = SCNNode(geometry: line)

            lineNode.position = SCNVector3(x: 0, y: 8Float(i) * 16, z: –5 + Float(i) * 10)

            self.scene?.rootNode.addChildNode(lineNode)

            

            lineNode.physicsBody = SCNPhysicsBody.staticBody()

        }

        

        // roller

        let roller = SCNNode()

        roller.position = SCNVector3(x: –15, y: 4, z: 0)

        self.scene?.rootNode.addChildNode(roller)

        

        var shapes = [AnyObject]()

        var transforms = [AnyObject]()

        

        let bar = SCNCylinder(radius: 0.5, height: 20)

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

        let barNode = SCNNode(geometry: bar)

        roller.addChildNode(barNode)

        

        shapes.append(SCNPhysicsShape(node: barNode, options: nil))

        transforms.append(NSValue(SCNMatrix4: barNode.transform))

        

        for i in 0..<2 {

            let fin = SCNBox(width: 0.2, height: 4, length: 16, chamferRadius: 0)

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

            let finNode = SCNNode(geometry: fin)

            if i == 0 {

                finNode.position = SCNVector3(x: 0, y: 8, z: 0)

                finNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: 0)

            } else {

                finNode.position = SCNVector3(x: 0, y: –8, z: 0)

                finNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(M_PI)/2.0)

            }

            roller.addChildNode(finNode)

            

            shapes.append(SCNPhysicsShape(node: finNode, options: nil))

            transforms.append(NSValue(SCNMatrix4: finNode.transform))

        }

        

        roller.physicsBody = SCNPhysicsBody.dynamicBody()

        roller.physicsBody?.physicsShape = SCNPhysicsShape(shapes: shapes, transforms: transforms)

        roller.physicsBody?.velocityFactor = SCNVector3Zero

        roller.physicsBody?.angularVelocityFactor = SCNVector3(x: 0, y: 1, z: 0)

        

        

        // dominos

        for i in 0..<20 {

            let domino = SCNBox(width: 0.3, height: 6, length: 3, chamferRadius: 0)

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

            

            let dominoNode = SCNNode(geometry: domino)

            dominoNode.name = “domino\(i)

            let x = 18Float(i % 10) * 3.5

            let y = Float(i / 10) * 164

            let z = –Float(i / 10) * 12 + 6

            dominoNode.position = SCNVector3(x: x, y: y, z: z)

            dominoNode.physicsBody = SCNPhysicsBody.dynamicBody()

            self.scene?.rootNode.addChildNode(dominoNode)

        }

    }

    

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

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

        target?.physicsBody?.applyForce(SCNVector3(x: –3, y: 0, z: 0), atPosition:SCNVector3(x: 0, y: 2, z: 0), impulse: true)

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

        self.scene?.rootNode.addChildNode(camera)

    }

    

}