iPhoneボール計算

数字と+-が描いてあるボールを落とすiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

import SpriteKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createBox()

        createCamera()

        createNumber()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.scene = SCNScene()

        sv.overlaySKScene = SKScene(size: sv.frame.size)

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

        sv.allowsCameraControl = true

        view.addSubview(sv)

        

        sceneView = sv

    }

    

    func createBox() {

        

        let boxplate = {(w : CGFloat, h : CGFloat, l : CGFloat, vec : SCNVector3) -> Void in

            let g = SCNBox(width: w, height: h, length: l, chamferRadius: 0)

            g.firstMaterial?.diffuse.contents = UIColor.blueColor().colorWithAlphaComponent(0.1)

            let node = SCNNode(geometry: g)

            node.position = vec

            node.physicsBody = SCNPhysicsBody.staticBody()

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

        }

        [(20, 40, 0.1, SCNVector3(x: 0, y: 0, z: 1)), (20, 40, 0.1, SCNVector3(x: 0, y: 0, z: –1)), (0.1, 40, 2, SCNVector3(x: –10, y: 0, z: 0)), (0.1, 40, 2, SCNVector3(x: 10, y: 0, z: 0)), (20, 0.1, 2, SCNVector3(x: 0, y: –20, z: 0))].foreach { (w, h, l, vec) in

            boxplate(w, h, l, vec)

        }

        

        let slope = {(x:Float, y:Float, w:Float) -> Void in

            let g = SCNBox(width: 18, height: 0.1, length: 2, chamferRadius: 0)

            g.firstMaterial?.diffuse.contents = UIColor.greenColor()

            let node = SCNNode(geometry: g)

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

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

            node.physicsBody = SCNPhysicsBody.staticBody()

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

        }

        [(2, 10, 0.2), (-2, –5, –0.35), (2, –18, 0.15)].foreach { (x,y,w) in

            slope(x, y, w)

        }

        

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

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

    }

    

    func createNumber() {

        let n = [Int](19).map { String($0) } + [“+”, “-“]

        n.foreach {(i, e) in

            let s = SKShapeNode(rectOfSize: CGSize(width: 25, height: 25), cornerRadius: 2)

            s.name = “btn_\(e)

            s.fillColor = UIColor.grayColor()

            s.position = CGPoint(x: i * 25 + 100, y: 70)

            self.sceneView?.overlaySKScene.addChild(s)

            

            let t = SKLabelNode(text: e)

            t.name = “btn_\(e)

            t.fontColor = UIColor.whiteColor()

            t.fontSize = 20

            t.verticalAlignmentMode = .Center

            s.addChild(t)

        }

        

        let disp = SKLabelNode(text: “0”)

        disp.name = “disp”

        disp.position = CGPoint(x: CGRectGetMidX(self.view.bounds), y: CGRectGetMidY(self.view.bounds))

        self.sceneView?.overlaySKScene.addChild(disp)

    }

    

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

        let p = touches.anyObject()!.locationInNode(self.sceneView?.overlaySKScene)

        if let name = self.sceneView?.overlaySKScene.nodeAtPoint(p).name {

            if name.hasPrefix(“btn_”) {

                let num = name.componentsSeparatedByString(“_”)[1]

                

                // cal

                calc(num)

                

                let ball = SCNSphere(radius: 0.9)

                ball.firstMaterial?.diffuse.contents = {

                    let l = CATextLayer();

                    l.string = num;

                    l.alignmentMode = kCAAlignmentCenter;

                    l.foregroundColor = UIColor.blackColor().CGColor

                    l.backgroundColor = UIColor(hue: 0.3, saturation: 0.1, brightness: 1, alpha: 0.8).CGColor

                    l.fontSize = 80;

                    l.frame = CGRectMake(0, 0, 200, 100);

                    return l

                    }()

                let ballNode = SCNNode(geometry: ball)

                ballNode.position = SCNVector3(x: 0, y: 18, z: 0)

                ballNode.physicsBody = SCNPhysicsBody.dynamicBody()

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

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

            }

        }

    }

    

    var dict = [“op”:“+”, “left”:“0”, “right”:“0”]

    func calc(s: String) {

        let disp = self.sceneView?.overlaySKScene.childNodeWithName(“disp”) as SKLabelNode

        

        switch s {

        case “+”, “-“:

            dict.updateValue(s, forKey: “op”)

            dict.updateValue(dict[“right”]!, forKey: “left”)

            dict.updateValue(“0”, forKey: “right”)

            break

        default:

            dict.updateValue(dict[“right”]! + s, forKey: “right”)

            break

        }

        

        var newDisp = “”

        switch dict[“op”]! {

            case “+”:

                let res = dict[“left”]!.toInt()! + dict[“right”]!.toInt()!

                newDisp = \(res)

            break

            

        case “-“:

            let res = dict[“left”]!.toInt()! – dict[“right”]!.toInt()!

            newDisp = \(res)

            break

            

        default:

            let res = dict[“left”]!.toInt()!

            newDisp = \(res)

            break

        }

        disp.text = newDisp

    }

}

extension Array {

    

    func foreach(doit:(T) -> Void) {for e in self {doit(e)}}

    func foreach(doit:(Int, T) -> Void) {for (i,e) in enumerate(self) {doit(i, e)}}

}