在寫上一個(gè)動(dòng)畫系列的時(shí)候?qū)W到了非常多的知識(shí),也認(rèn)識(shí)了很多人。例如受邀進(jìn)入了某個(gè)神秘的動(dòng)效組織,全是一線的大神啊。有UI的大牛、UED的大神、iOS的大神。加入組織可以閱讀這里:加入CRAnimation組織 。
真的是發(fā)現(xiàn)堅(jiān)持寫作,其實(shí)也是逼迫自己堅(jiān)持不斷學(xué)習(xí)的過程。那么,來來來,星辰大海我們又開始啟程了。這次這個(gè)系列吶,我管它叫《藍(lán)牙和傳感器小兄弟們》。先暫時(shí)這么叫著,等想到什么好聽的名字再改。計(jì)劃是八篇文章。
咳咳,至于最終是不是八篇就不知道了。反正現(xiàn)在先這么計(jì)劃著,沒有計(jì)劃就沒有辦法實(shí)施嘛。實(shí)在不行就改需求,需求就是用來改的......-_-+++。所以,以下目錄
第一篇:加速傳感器
第二篇:陀螺儀
第三篇:磁力計(jì)
第四篇:距離傳感器
第五篇:指紋識(shí)別傳感器
第六篇:藍(lán)牙之MultipeerConnectivity
第七篇:藍(lán)牙之Core Bluetooth
第八篇:想個(gè)好玩的例子,把前面的都綜合一下。
這個(gè)系列的內(nèi)容模擬器基本上都不支持,需要真機(jī)測(cè)試才可以。所以掏出手機(jī),咱們一起來搞事情吧。為了能夠錄到手機(jī)效果,也是小費(fèi)了一番周折。
咱們通過實(shí)現(xiàn)一個(gè)隨屏幕旋轉(zhuǎn)的圖片來看看加速計(jì)怎么玩。下面是完成后的效果視頻截圖。請(qǐng)無視我的小背心:
有一些APP除了絢麗的界面之外,還會(huì)有一些特殊的功能。例如微信的搖一搖,各種健康軟件的計(jì)步器,指南針等等。這些APP其實(shí)都用到了iOS當(dāng)中一個(gè)核心運(yùn)動(dòng)框架,叫做CoreMotion
。
CoreMotion可以從內(nèi)置的傳感器中獲取數(shù)據(jù),這些傳感器包括陀螺儀、加速器和磁力計(jì)。更值得嘚瑟的是,蘋果集成了很多算法,可以直接輸出剝離重力加速因素的加速度信息。好流弊的樣紙。
1. 加速計(jì)介紹
iPhone、iPad、iWatch都可以測(cè)量x,y,x三個(gè)軸上的加速力。加速力就是當(dāng)物體在加速過程中作用在物體上的力。用一張圖說明一下下:
2. 加速計(jì)的使用
既然說了加速計(jì)是通過CoreMotion
這個(gè)框架來管理的,而且蘋果繼承了辣么多算法,所以CoreMotion一定還有一個(gè)Manager。官方是這么介紹CMMotionManager:
A CMMotionManager object is the gateway to the motion services provided by iOS. These services provide an app with accelerometer data, rotation-rate data, magnetometer data, and other device-motion data such as attitude. These types of data originate with a device’s accelerometers and (on some models) its magnetometer and gyroscope.
所以只要使用Motion的服務(wù),咱們一定需要使用CMMotionManager。
使用步驟如下:
- 初始化CMMotionManager管理對(duì)象;
- 調(diào)用管理對(duì)象的對(duì)象方法獲取數(shù)據(jù);
- 處理數(shù)據(jù);
- 當(dāng)不需要使用的時(shí)候,停止獲取數(shù)據(jù)。
//初始化全局管理對(duì)象
- (CMMotionManager *)manager{
if (!_manager) {
_manager = [[CMMotionManager alloc] init];
}
return _manager;
}
//停止獲取加速計(jì)數(shù)據(jù)。在停止之前判斷一下是否還處在活動(dòng)
if ( self.manager.accelerometerActive) {
[self.manager stopAccelerometerUpdates];
NSLog(@"關(guān)閉啦");
}
3. 獲取加速計(jì)數(shù)據(jù)的兩種方式
CoreMotion中有2種獲取數(shù)據(jù)方式,一種叫做PUSH的方式,一種叫做PULL的方式。
顧名思義,PUSH就是被動(dòng)的獲取。設(shè)定完了之后,線程定時(shí)把獲取到的數(shù)據(jù)推送回來。可想而知,對(duì)于資源的消耗是會(huì)稍微大一點(diǎn)的。
PULL,就是要去索取。拉一下才會(huì)獲取到數(shù)據(jù)。不要不給。
3.1 PULL的方式
- (void)useAccelerometerPull{
//判斷加速度計(jì)可不可用
if (self.manager.accelerometerAvailable){
//設(shè)置加速計(jì)多久采樣一次
self.manager.accelerometerUpdateInterval = 0.1;
//開始更新,后臺(tái)線程開始運(yùn)行。這是Pull方式。
[self.manager startAccelerometerUpdates];
}
//獲取并處理加速度計(jì)數(shù)據(jù)。這里我們就只是簡(jiǎn)單的做了打印。
NSLog(@"X = %f,Y = %f,Z = %f",self.manager.accelerometerData.acceleration.x,self.manager.accelerometerData.acceleration.y,self.manager.accelerometerData.acceleration.z);
}
3.2 PUSH的方式
- (void)useAccelerometerPush{
//判斷加速度計(jì)可不可用,判斷加速度計(jì)是否開啟
if (self.manager.accelerometerAvailable){
//設(shè)置加速計(jì)多久采樣一次
self.manager.accelerometerUpdateInterval = 0.1;
//Push方式獲取和處理數(shù)據(jù),這里我們一樣只是做了簡(jiǎn)單的打印。把采樣的工作放在了主線程中。
[self.manager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMAccelerometerData *accelerometerData, NSError *error){
NSLog(@"X = %f,Y = %f,Z = %f",self.manager.accelerometerData.acceleration.x,self.manager.accelerometerData.acceleration.y,self.manager.accelerometerData.acceleration.z);
}];
} else{
NSLog(@"不可用");
}
}
3.3 打印結(jié)果
我們可以愉快的看到XYZ軸的數(shù)值在瘋狂地變化。這中間我的手機(jī)屏幕一直在晃動(dòng)。
4. 實(shí)現(xiàn)圖片永遠(yuǎn)水平方向
4.1 思路
STEP1:為了能夠讓圖片無論在設(shè)備如何傾斜的情況下都保持水平,肯定首先要獲取到屏幕的旋轉(zhuǎn)。
STEP2:用很高的頻率獲取到這個(gè)數(shù)值之后,來旋轉(zhuǎn)圖片。
STEP 3: 就結(jié)束了。神馬?!!!!開玩笑啦。其實(shí)在這個(gè)過程中可以發(fā)現(xiàn),圖片在旋轉(zhuǎn)的時(shí)候會(huì)有一些抖動(dòng)。腫么辦呢?我們可以考對(duì)一定時(shí)間內(nèi)獲取的數(shù)據(jù)取平均值來緩和。在使用了下次文章介紹的陀螺儀之后,抖動(dòng)效果也會(huì)得到明顯的改善。這一部分的代碼部分宅胖兒就沒有實(shí)現(xiàn)了,自己嘗試一下?!啦啦啦啦啦。
4.2 實(shí)現(xiàn)
- (void)keepBalance{
if (self.manager.accelerometerAvailable) {
//設(shè)置加速計(jì)采樣頻率
self.manager.accelerometerUpdateInterval = 0.01f;
[self.manager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
// 計(jì)算圖片的水平傾斜角度。這里沒有實(shí)現(xiàn)Z軸的形變,所以咱們只能在XY軸上變換。有興趣的童鞋自己實(shí)現(xiàn)Z軸好不好?
double rotation = atan2(accelerometerData.acceleration.x, accelerometerData.acceleration.y) - M_PI;
self.imageView.transform = CGAffineTransformMakeRotation(rotation);
}];
}
}
4.3 關(guān)于形變角度atan2的說明
//計(jì)算旋轉(zhuǎn)角度
double rotation = atan2(accelerometerData.acceleration.x, accelerometerData.acceleration.y) - M_PI;
這個(gè)里面用到了一個(gè)C語言的函數(shù)。atan2返回的是原點(diǎn)至點(diǎn)(x,y)的方位角,即與 x 軸的夾角。
你可能從未用過atan2這個(gè)函數(shù),它和atan類似,但atan返回值范圍是(-PI/2,PI/2),atan2返回值范圍是(-PI,PI),并且他有兩個(gè)參數(shù)。
atan2這個(gè)函數(shù)我們其實(shí)可以在很多地方都看到,Android、JS、PHP等等都能遇見到。如果想進(jìn)一步深入了解,可以移步百度百科,感覺講的還算挺清楚的。百度百科關(guān)于atan2的鏈接;
維基百科關(guān)于atan2的鏈接。
個(gè)人感覺還是有必要好好了解一下的。
好啦手工~下次咱們用陀螺儀做一個(gè)水平滾動(dòng)的小球的游戲玩玩
多謝各位大爺評(píng)論、點(diǎn)贊、打賞。
源代碼下載地址:OC+Swift兩版。下載地址
iOS傳感器系列之一:加速傳感器
iOS傳感器系列之二:陀螺儀
iOS傳感器系列之三:磁力計(jì)
iOS傳感器系列之四:指紋傳感器&距離傳感器