说明
本系列文章是对<3D Apple Games by Tutorials>一书的学习记录和体会此书对应的代码地址
相机约束
// 1.拿到相机节点
cameraNode = scnScene.rootNode.childNodeWithName("camera", recursively:
true)!
// 2.添加lookAt约束,让相机始终朝向ballNode小球节点
let constraint = SCNLookAtConstraint(target: ballNode)
cameraNode.constraints = [constraint]
Gimbal locking万向节锁
当使用SCNLookAtConstraint时,Scene Kit不管被朝向的对象如何移动,旋转都会让相机对着他.但是有些时候会转到一些奇怪的角度,导致相机发生向左或向右的倾斜,对于灯光是没问题的,但相机就不可以,我们总是希望相机保持水平方向.
因此用到万向节锁
constraint.gimbalLockEnabled = true
更改物体的运动状态和位置
//根据手机加速度传感器数据,移动小球
func updateMotionControl() {
// 1.每0.1秒更新传感器参数,构造为向量
if game.state == GameStateType.Playing {
motion.getAccelerometerData(0.1) { (x,y,z) in
self.motionForce = SCNVector3(x: Float(x) * 0.05, y:0, z: Float(y+0.8) * -0.05)
}
// 2.小球的速度改变
ballNode.physicsBody!.velocity += motionForce
}
}
//让相机跟着小球平滑移动
func updateCameraAndLights() {
// 1.小球呈现位置与相机当前位置的差,每次移动0.01
let lerpX = (ballNode.presentationNode.position.x - cameraFollowNode.position.x) * 0.01
let lerpY = (ballNode.presentationNode.position.y - cameraFollowNode.position.y) * 0.01
let lerpZ = (ballNode.presentationNode.position.z - cameraFollowNode.position.z) * 0.01
cameraFollowNode.position.x += lerpX
cameraFollowNode.position.y += lerpY
cameraFollowNode.position.z += lerpZ
// 2.灯光位置也跟随相机位置变化
lightFollowNode.position = cameraFollowNode.position
// 3.进入暂停状态时,相机欧拉角沿y轴旋转0.005
if game.state == GameStateType.TapToPlay {
cameraFollowNode.eulerAngles.y += 0.005
}
}
传感器工具类代码
import Foundation
import CoreMotion
class CoreMotionHelper {
let motionManager = CMMotionManager()
init() {
}
func getAccelerometerData(interval: NSTimeInterval = 0.1, closure: ((x: Double, y: Double, z: Double) -> ())? ){
if motionManager.accelerometerAvailable {
motionManager.accelerometerUpdateInterval = interval
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
(data: CMAccelerometerData?, error: NSError?) -> Void in
if closure != nil{
closure!(x: data!.acceleration.x,y: data!.acceleration.y,z: data!.acceleration.z)
}
}
}
}
}
网友评论