
カードを左右の箱に仕分けていくiPhoneアプリのサンプルコードを書いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
var cards = [SCNNode]()
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
self.createRack()
self.createCamera()
self.createLight()
for i in 0…2 {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.2 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()!, {
self.createCard()
});
}
}
func setupScene() {
let sv = SCNView(frame: self.view.bounds)
sv.scene = SCNScene()
sv.backgroundColor = UIColor.darkGrayColor()
self.view.addSubview(sv)
self.sceneView = sv
}
func createRack() {
for i in 0..<2 {
let rack = SCNBox(width: 10, height: 6, length: 1, chamferRadius: 0)
rack.firstMaterial?.diffuse.contents = UIColor(hue: 0.35 + CGFloat(i) * 0.35, saturation: 0.4, brightness: 1, alpha: 1)
let rackNode = SCNNode(geometry: rack)
rackNode.name = “rack\(i)“
rackNode.position = SCNVector3(x: Float(i) * 12.0 – 6.0, y: 18.0, z: 0)
self.sceneView?.scene?.rootNode.addChildNode(rackNode)
}
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 40)
self.sceneView?.scene?.rootNode.addChildNode(camera)
}
func createLight() {
let light = SCNLight()
light.type = SCNLightTypeSpot
light.castsShadow = true
light.spotOuterAngle = 100.0
let lightNode = SCNNode()
lightNode.light = light
lightNode.position = SCNVector3(x: 0, y: 0, z: 150)
self.sceneView?.scene?.rootNode.addChildNode(lightNode)
let light2 = SCNLight()
light2.type = SCNLightTypeAmbient
let lightNode2 = SCNNode()
lightNode2.light = light2
lightNode2.position = SCNVector3(x: 0, y: 0, z: 50)
self.sceneView?.scene?.rootNode.addChildNode(lightNode2)
}
func createCard() {
self.sceneView?.scene?.rootNode.enumerateChildNodesUsingBlock({ (node, stop) in
if node.name == “card” {
node.runAction(SCNAction.moveBy(SCNVector3(x: 0, y: 1, z: 2), duration: 0.3))
}
})
let card = SCNBox(width: 4.2, height: 5, length: 0.1, chamferRadius: 0)
let hue = CGFloat(arc4random() % 10) * 0.1
card.firstMaterial?.diffuse.contents = UIColor(hue: hue, saturation: 0.5, brightness: 0.7, alpha: 1)
let cardNode = SCNNode(geometry: card)
cardNode.name = “card”
cardNode.position = SCNVector3(x: 0, y: –2, z: 26)
self.sceneView?.scene?.rootNode.addChildNode(cardNode)
for i in 0..<2 {
let rackbtn = SCNBox(width: 1, height: 0.8, length: 0.1, chamferRadius: 0)
rackbtn.firstMaterial?.diffuse.contents = UIColor(hue: 0.35 + CGFloat(i) * 0.35, saturation: 0.4, brightness: 1, alpha: 1)
let rackbtnNode = SCNNode(geometry: rackbtn)
rackbtnNode.name = “btn\(i)“
rackbtnNode.position = SCNVector3(x: Float(i) * 3.0 – 1.5, y: –1.0, z: 0.001)
cardNode.addChildNode(rackbtnNode)
}
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let p = touches.anyObject()!.locationInView(self.sceneView)
if let hit = self.sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey:true])?.first?.node {
if hit.name!.hasPrefix(“btn”) {
let rackname = “rack\(hit.name![3…3])“
let rack = self.sceneView?.scene?.rootNode.childNodeWithName(rackname, recursively: false)
hit.parentNode!.runAction(SCNAction.moveTo(SCNVector3(x: rack!.position.x – 2.5 + 0.4 * Float(self.cards.count), y: rack!.position.y – 0.2, z: rack!.position.z + 1 + Float(self.cards.count) * 0.01), duration: 0.2))
hit.parentNode!.name = “categorized”
self.cards.append(hit.parentNode!)
self.createCard()
}
}
}
}
extension String {
subscript (r: Range<Int>) -> String {
get {
let subStart = advance(self.startIndex, r.startIndex, self.endIndex)
let subEnd = advance(subStart, r.endIndex – r.startIndex, self.endIndex)
return self.substringWithRange(Range(start: subStart, end: subEnd))
}
}
}