
回転する板をつかって上下のドミノを倒す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: 8 – Float(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 = 18 – Float(i % 10) * 3.5
let y = Float(i / 10) * 16 – 4
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)
}
}