丸いチョコのボールを箱から出すiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate {
weak var sceneView : SCNView?
var turn : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
self.createPlate()
self.createBox()
self.createChocoball()
self.createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.backgroundColor = UIColor(hue: 0.25, saturation: 0.1, brightness: 0.75, alpha: 1)
sv.autoenablesDefaultLighting = true
sv.allowsCameraControl = true
sv.delegate = self
view.addSubview(sv)
sceneView = sv
}
func createPlate() {
let plate = SCNCylinder(radius: 10, height: 0.5)
plate.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()
let plateNode = SCNNode(geometry: plate)
plateNode.position = SCNVector3(x: 0, y: –8, z: 0)
sceneView?.scene?.rootNode.addChildNode(plateNode)
plateNode.physicsBody = SCNPhysicsBody.staticBody()
}
func createBox() {
let box = SCNNode()
box.name = “box”
var shapes = [SCNPhysicsShape]()
var transforms = [NSValue]()
for i in 0…5 {
let wall = {() -> SCNBox in
switch i {
case 1, 3:
return SCNBox(width: 5, height: 8, length: 0.01, chamferRadius: 0)
case 4:
return SCNBox(width: 5, height: 0.01, length: 2, chamferRadius: 0)
case 5:
return SCNBox(width: 2.5, height: 0.01, length: 2, chamferRadius: 0)
default:
return SCNBox(width: 0.01, height: 8, length: 2, chamferRadius: 0)
}
}()
wall.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.1, brightness: 1, alpha: 1)
let wallNode = SCNNode(geometry: wall)
wallNode.position = {
switch i {
case 0:
return SCNVector3(x: 2.5, y: 0, z: 0)
case 1:
return SCNVector3(x: 0, y: 0, z: 1)
case 2:
return SCNVector3(x: –2.5, y: 0, z: 0)
case 3:
return SCNVector3(x: 0, y: 0, z: –1)
case 4:
return SCNVector3(x: 0, y: –4, z: 0)
default:
return SCNVector3(x: 1.25, y: 4, z: 0)
}
}()
box.addChildNode(wallNode)
shapes.append(SCNPhysicsShape(node: wallNode, options: nil))
transforms.append(NSValue(SCNMatrix4: wallNode.transform))
}
sceneView?.scene?.rootNode.addChildNode(box)
box.physicsBody = SCNPhysicsBody.dynamicBody()
box.physicsBody?.physicsShape = SCNPhysicsShape(shapes: shapes, transforms: transforms)
let hinge = SCNPhysicsHingeJoint(body: box.physicsBody!, axis: SCNVector3(x: 0, y: 0, z: 1), anchor: SCNVector3(x: 0, y: 0, z: 0))
sceneView?.scene?.physicsWorld.addBehavior(hinge)
let flap = SCNBox(width: 2.5, height: 0.01, length: 2, chamferRadius: 0)
flap.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let flapNode = SCNNode(geometry: flap)
flapNode.position = SCNVector3(x: –1.25, y: 4, z: 0)
sceneView?.scene?.rootNode.addChildNode(flapNode)
flapNode.physicsBody = SCNPhysicsBody.dynamicBody()
let flapConnect = SCNPhysicsHingeJoint(bodyA: flapNode.physicsBody!, axisA: SCNVector3(x: 0, y: 0, z: 1), anchorA: SCNVector3(x: 1.25, y: 0, z: 0), bodyB: box.physicsBody!, axisB: SCNVector3(x: 0, y: 0, z: 1), anchorB: SCNVector3(x: 0, y: 4, z: 0))
sceneView?.scene?.physicsWorld.addBehavior(flapConnect)
}
func createChocoball() {
for i in 0…5 {
let ball = SCNSphere(radius: 0.8)
ball.firstMaterial?.diffuse.contents = UIColor.brownColor()
let ballNode = SCNNode(geometry: ball)
ballNode.position = SCNVector3(x: (i%2 == 0) ? –0.8 : 0.8, y: Float(i) * 0.6, z: 0)
sceneView?.scene?.rootNode.addChildNode(ballNode)
ballNode.physicsBody = SCNPhysicsBody.dynamicBody()
}
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 30)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.turn = !self.turn
}
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
let box = sceneView?.scene?.rootNode.childNodeWithName(“box”, recursively: false)
if self.turn {
box?.physicsBody?.angularVelocity = SCNVector4(x: 0, y: 0, z: 1, w: 0.4)
}
if box?.presentationNode().rotation.w > 2.3 {
box?.physicsBody?.angularVelocity = SCNVector4Zero
}
}
}