场景
就是加速度传感器。
比如玩小球游戏,通过模拟重力加速度控制小球运动。
技术点
传感器相关配置
/// 传感器
private let motionManager = CMMotionManager()
// 判断设备是否支持加速度传感器
if motionManager.isAccelerometerAvailable {
jx_startAccelerometerAction()
} else {
print("加速度传感器不支持")
}
// 设置加速度传感器更新数据时间
motionManager.accelerometerUpdateInterval = 1 / 30
// 开启监听
motionManager.startAccelerometerUpdates(to: .main) {[weak self] data, error in {
}
记录累计速度
/// 速度累计
var velocity: CGPoint = .zero
// 开启监听
motionManager.startAccelerometerUpdates(to: .main) {[weak self] data, error in
guard let accelerometerData = data, let _ = self else { return }
self?.velocity = CGPointMake((self?.velocity.x ?? 0) + accelerometerData.acceleration.x, (self?.velocity.y ?? 0) - accelerometerData.acceleration.y)
}
有趣的是acceleration数据里y的值和屏幕数据相反,应该是UIKit坐标系原因。
此外,acceleration数据除了平面x、y以外,还有z,想要3D效果的话可以用上。
完整代码
import UIKit
import CoreMotion
/// 加速度传感器
class JX_AccelerometerViewController: JX_BaseViewController {
/// 速度累计
var velocity: CGPoint = .zero
/// 传感器
private let motionManager = CMMotionManager()
/// 展示view
private let ball = UIView(frame: CGRectMake(200, 200, 40, 40))
/// 碰触后速度比
private let velocityAfter: CGFloat = -0.7
override func viewDidLoad() {
super.viewDidLoad()
// 添加球
ball.backgroundColor = .red
ball.layer.cornerRadius = 20
ball.layer.masksToBounds = true
view.addSubview(ball)
// 判断设备是否支持加速度传感器
if motionManager.isAccelerometerAvailable {
jx_startAccelerometerAction()
} else {
print("加速度传感器不支持")
}
}
deinit {
if motionManager.isAccelerometerAvailable {
motionManager.stopAccelerometerUpdates()
}
}
/// 开启加速度传感器
func jx_startAccelerometerAction() {
// 设置加速度传感器更新数据时间
motionManager.accelerometerUpdateInterval = 1 / 30
// 开启监听
motionManager.startAccelerometerUpdates(to: .main) {[weak self] data, error in
guard let accelerometerData = data, let _ = self else { return }
self?.velocity = CGPointMake((self?.velocity.x ?? 0) + accelerometerData.acceleration.x, (self?.velocity.y ?? 0) - accelerometerData.acceleration.y)
self?.ball.center = CGPointMake((self?.ball.center.x)! + (self?.velocity.x)!, (self?.ball.center.y)! + (self?.velocity.y)!)
self?.jx_checkBallStatus()
}
}
/// 矫正速度与位置(当球超出边界时)
func jx_checkBallStatus() {
autoreleasepool {
var x0 = self.ball.center.x //球圆心x坐标
var y0 = self.ball.center.y //球圆心y坐标
let r0 = self.ball.bounds.size.width / 2.0 //球半径
let w = view.bounds.size.width //屏幕宽度
let h = view.bounds.size.height //屏幕高度
if x0 + r0 > w {
x0 = w - r0
velocity.x *= velocityAfter
} else if x0 < r0 {
x0 = r0
velocity.x *= velocityAfter
}
if y0 + r0 > h {
y0 = h - r0
velocity.y *= velocityAfter
} else if y0 < r0 {
y0 = r0
velocity.y *= velocityAfter
}
ball.center = CGPointMake(x0, y0)
}
}
}
其他
没有什么了,就先这样吧。