
スリットの間に弾を通すiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createLine()
createSlit()
createPlayer()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.backgroundColor = UIColor(hue: 0.35, saturation: 0.2, brightness: 1, alpha: 1)
sv.allowsCameraControl = true
sv.autoenablesDefaultLighting = true
view.addSubview(sv)
sceneView = sv
}
func createLine() {
let line = SCNBox(width: 150, height: 0.1, length: 5, chamferRadius: 0)
line.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.3, brightness: 1, alpha: 0.2)
let lineNode = SCNNode(geometry: line)
lineNode.physicsBody = SCNPhysicsBody.staticBody()
sceneView?.scene?.rootNode.addChildNode(lineNode)
}
func createSlit() {
[Int](0…3).each {i in
let slit = {() -> SCNNode in
let s = SCNNode()
[Int](0…3).each {j in
let box = SCNBox(width: 0.5, height: 4, length: 10, chamferRadius: 0)
box.firstMaterial?.diffuse.contents = UIColor(hue: 0.9, saturation: 0.5, brightness: 0.6, alpha: 1)
let boxNode = SCNNode(geometry: box)
boxNode.transform = SCNMatrix4Translate(boxNode.transform, 0, 5, 0)
boxNode.transform = SCNMatrix4Rotate(boxNode.transform, Float(j) * Float(M_PI) * 0.5, 1, 0, 0)
s.addChildNode(boxNode)
}
return s
}()
slit.position = SCNVector3(x: –5 + Float(i) * 20, y:0 , z: 0)
slit.physicsBody = SCNPhysicsBody.staticBody()
slit.physicsBody?.physicsShape = SCNPhysicsShape(node: slit, options: [SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConvexHull])
self.sceneView?.scene?.rootNode.addChildNode(slit)
let (y, z) = (4 * cos(Float(M_PI) * 0.5 * Float(i)), 4 * sin(Float(M_PI) * 0.5 * Float(i)))
slit.runAction(SCNAction.repeatActionForever(SCNAction.sequence([SCNAction.moveTo(SCNVector3(x:slit.position.x , y: y, z: z), duration: 1.0), SCNAction.moveTo(SCNVector3(x: slit.position.x, y: 0, z: 0), duration: 1)])))
}
}
func createPlayer() {
let player = SCNCylinder(radius: 2, height: 1)
player.firstMaterial?.diffuse.contents = UIColor(hue: 0.7, saturation: 0.2, brightness: 0.5, alpha: 1)
let playerNode = SCNNode(geometry: player)
playerNode.name = “player”
playerNode.position = SCNVector3(x: –15, y: 4, z: 0)
playerNode.physicsBody = SCNPhysicsBody.dynamicBody()
sceneView?.scene?.rootNode.addChildNode(playerNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.camera?.zFar = 300
camera.position = SCNVector3(x: 0, y: 0, z: 100)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let player = sceneView?.scene?.rootNode.childNodeWithName(“player”, recursively: false)
player?.physicsBody?.friction = 0
player?.physicsBody?.applyForce(SCNVector3(x: 70, y: 0, z: 0), impulse: true)
player?.runAction(SCNAction.sequence([SCNAction.waitForDuration(3.0), SCNAction.runBlock { (n) -> Void in
n.removeFromParentNode()
self.createPlayer()
}]))
}
}
extension Array {
func each(doit:(T) -> Void) {for i in self { doit(i) }}
}