
三角と四角のプレートをパズルっぽく並べるiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var scene : SCNScene?
weak var sceneView : SCNView?
weak var selected : SCNNode?
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.lightGrayColor()
self.setupScene()
self.createPlate()
self.createPiece()
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.orangeColor()
self.view.addSubview(sv)
self.scene = sv.scene
self.sceneView = sv
}
func createPlate() {
let plate = SCNBox(width: 50, height: 1, length: 50, chamferRadius: 0)
plate.firstMaterial?.diffuse.contents = UIColor.brownColor()
let plateNode = SCNNode(geometry: plate)
plateNode.name = “plate”
plateNode.physicsBody = SCNPhysicsBody.staticBody()
plateNode.physicsBody?.friction = 0.9;
self.scene?.rootNode.addChildNode(plateNode)
}
func createPiece() {
let triangle = UIBezierPath()
triangle.moveToPoint(CGPointMake(-3, –3))
triangle.addLineToPoint(CGPointMake(3, –3))
triangle.addLineToPoint(CGPointMake(-3, 3))
let a = SCNShape(path: triangle, extrusionDepth: 1.0)
a.firstMaterial?.diffuse.contents = UIColor.redColor()
let aNode = SCNNode(geometry: a)
aNode.name = “piece”
aNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI)/2.0)
aNode.position = SCNVector3(x: 0, y: 3, z: –10)
aNode.physicsBody = SCNPhysicsBody.dynamicBody()
aNode.physicsBody?.physicsShape = SCNPhysicsShape(geometry: a, options: [SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConcavePolyhedron])
self.scene?.rootNode.addChildNode(aNode)
let b = SCNShape(path: triangle, extrusionDepth: 1.0)
b.firstMaterial?.diffuse.contents = UIColor.blueColor()
let bNode = SCNNode(geometry: a)
bNode.name = “piece”
bNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI)/2.0)
bNode.position = SCNVector3(x: 10, y: 3, z: 10)
bNode.transform = SCNMatrix4Rotate(bNode.transform, Float(M_PI), 0, 1, 0)
bNode.physicsBody = SCNPhysicsBody.dynamicBody()
bNode.physicsBody?.physicsShape = SCNPhysicsShape(geometry: a, options: [SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConcavePolyhedron])
self.scene?.rootNode.addChildNode(bNode)
let c = SCNBox(width: 10, height: 1, length: 6, chamferRadius: 0)
c.firstMaterial?.diffuse.contents = UIColor.greenColor()
let cNode = SCNNode(geometry: c)
cNode.name = “piece”
cNode.position = SCNVector3(x: 15, y: 3, z: –8)
cNode.physicsBody = SCNPhysicsBody.dynamicBody()
self.scene?.rootNode.addChildNode(cNode)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let p = touches.anyObject()!.locationInView(self.sceneView)
let hits = self.sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey:true])
if hits?.count > 0 {
let node = hits![0].node
if node.name == “piece” {
self.selected = node
self.selected?.physicsBody?.velocityFactor = SCNVector3Zero
}
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
// plate position
let p = touches.anyObject()!.locationInView(self.sceneView)
if let hits = self.sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey:true]) {
for hit in hits {
if hit.node.name == “plate” {
let p = hit.worldCoordinates
self.selected?.position = SCNVector3(x: p.x, y: p.y + 3, z: p.z)
}
}
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
self.selected?.physicsBody?.velocityFactor = SCNVector3(x: 1, y: 1, z: 1)
self.selected?.physicsBody?.velocity = SCNVector3Zero
self.selected?.physicsBody?.applyForce(SCNVector3(x: 0, y: 1, z: 0), impulse: false)
self.selected = nil
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 50, z: 50)
camera.rotation = SCNVector4Make(1, 0, 0, –0.5)
self.scene?.rootNode.addChildNode(camera)
}
}