说明
本系列文章是对<3D Apple Games by Tutorials>一书的学习记录和体会
此书对应的代码地址
SceneKit系列文章目录
相机约束
// 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) inself.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.01let lerpX = (ballNode.presentationNode.position.x - cameraFollowNode.position.x) * 0.01let lerpY = (ballNode.presentationNode.position.y - cameraFollowNode.position.y) * 0.01let lerpZ = (ballNode.presentationNode.position.z - cameraFollowNode.position.z) * 0.01cameraFollowNode.position.x += lerpXcameraFollowNode.position.y += lerpYcameraFollowNode.position.z += lerpZ// 2.灯光位置也跟随相机位置变化lightFollowNode.position = cameraFollowNode.position// 3.进入暂停状态时,相机欧拉角沿y轴旋转0.005if game.state == GameStateType.TapToPlay {cameraFollowNode.eulerAngles.y += 0.005}}
复制代码
传感器工具类代码
import Foundation
import CoreMotionclass CoreMotionHelper {let motionManager = CMMotionManager()init() {}func getAccelerometerData(interval: NSTimeInterval = 0.1, closure: ((x: Double, y: Double, z: Double) -> ())? ){if motionManager.accelerometerAvailable {motionManager.accelerometerUpdateInterval = intervalmotionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {(data: CMAccelerometerData?, error: NSError?) -> Void inif closure != nil{closure!(x: data!.acceleration.x,y: data!.acceleration.y,z: data!.acceleration.z)}}}}
}
复制代码