数字と+-が描いてあるボールを落とす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](1…9).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)}}
}