
コップにボールを入れるiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createGround()
createCup()
createBall()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.backgroundColor = UIColor(hue: 0, saturation: 0.3, brightness: 0.8, alpha: 1)
sv.scene = SCNScene()
sv.autoenablesDefaultLighting = true
view.addSubview(sv)
sceneView = sv
}
func createGround() {
let box = SCNCylinder(radius: 10, height: 1)
box.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.3, brightness: 0.9, alpha: 1)
let boxNode = SCNNode(geometry: box)
boxNode.physicsBody = SCNPhysicsBody.staticBody()
sceneView?.scene?.rootNode.addChildNode(boxNode)
}
func createCup() {
let cup = SCNTube(innerRadius: 1.6, outerRadius: 1.8, height: 2.5)
cup.firstMaterial?.diffuse.contents = UIColor(hue: 0.2, saturation: 0.6, brightness: 0.9, alpha: 1).colorWithAlphaComponent(0.8)
let cupNode = SCNNode(geometry: cup)
cupNode.position = SCNVector3(x: 0, y: 1.7, z: –8)
cupNode.physicsBody = SCNPhysicsBody.staticBody()
cupNode.physicsBody?.physicsShape = SCNPhysicsShape(geometry: cup, options: [SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron])
sceneView?.scene?.rootNode.addChildNode(cupNode)
}
func createBall (){
let ball = SCNSphere(radius: 0.8)
ball.firstMaterial?.diffuse.contents = UIColor.greenColor()
let ballNode = SCNNode(geometry: ball)
ballNode.name = “ball”
ballNode.position = SCNVector3(x: 0, y: 1.2, z: 8)
sceneView?.scene?.rootNode.addChildNode(ballNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 20, z:30)
camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: –0.6)
camera.transform = SCNMatrix4Rotate(camera.transform, 0.5, 0, 1, 0)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
let p = touches.anyObject()!.locationInView(sceneView)
let ball = sceneView?.scene?.rootNode.childNodeWithName(“ball”, recursively: false)
sceneView?.scene?.rootNode.childNodes
.filter {($0 as SCNNode).name == “marker”}
.each {i in i.removeFromParentNode(); }
let mid = CGRectGetMidY(self.sceneView!.frame)
for (var i=0; i < Int(p.y – mid); i+=10) {
let marker = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
marker.firstMaterial?.diffuse.contents = UIColor(hue: 0.6, saturation: 1, brightness: 0.8, alpha: 1)
let markerNode = SCNNode(geometry: marker)
markerNode.name = “marker”
markerNode.position = SCNVector3(x: Float(ball!.position.x), y: Float(ball!.position.y) + Float(i)/20.0, z: ball!.position.z – Float(i)/20.0)
sceneView?.scene?.rootNode.addChildNode(markerNode)
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
let p = touches.anyObject()!.locationInView(sceneView)
let ball = sceneView?.scene?.rootNode.childNodeWithName(“ball”, recursively: false)
sceneView?.scene?.rootNode.childNodes
.filter {($0 as SCNNode).name == “marker”}
.each {i in i.removeFromParentNode(); }
let dl = Float(p.y – CGRectGetMidY(self.sceneView!.bounds))
ball?.physicsBody = SCNPhysicsBody.dynamicBody()
ball?.physicsBody?.applyForce(SCNVector3(x: 0, y: dl/10.0, z: -dl/10.0), impulse: true)
ball?.name = “”
func delay(delay:Double, doit:() -> Void) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), doit)
}
delay(1.0) {
self.createBall()
}
delay(10.0) {
ball!.removeFromParentNode()
}
}
}
extension Array {
func each(doit:T->Void) { for i in self {doit(i);}}
}