iOS傳感器:使用陀螺儀完成一個(gè)小球撞壁的小游戲

上一次借著實(shí)現(xiàn)一個(gè)隨屏幕旋轉(zhuǎn)的小玩意甸怕,了解了iPhone內(nèi)置的加速計(jì)挠羔。今天咱們繼續(xù)搞點(diǎn)好玩的東東盖奈。按照計(jì)劃這次要看看陀螺儀了。

最終咱們會(huì)完成一個(gè)小球撞壁的小游戲,一個(gè)超級(jí)賤的利用陀螺儀的APP磁奖。小球可以感受到重力囊拜,從而能夠隨著手機(jī)的運(yùn)動(dòng)來(lái)一起運(yùn)動(dòng)。為了增加一點(diǎn)點(diǎn)趣味性比搭,對(duì)小球的運(yùn)動(dòng)范圍做了限制冠跷。當(dāng)小球碰到屏幕的邊緣的時(shí)候,會(huì)進(jìn)行反彈身诺,相反方向運(yùn)動(dòng)蜜托。咱們一起來(lái)看看實(shí)現(xiàn)后的實(shí)況錄像:

今天的代碼比起上次的加速計(jì)稍微多了一點(diǎn)點(diǎn),所以就提供了源碼供大家批評(píng)霉赡。同時(shí)由于這部分Swfit和Objective-C略微有不太一樣的地方橄务,所以源碼提供了兩版。

其實(shí)不管是加速計(jì)還是今天的陀螺儀穴亏,都是用到了上次說(shuō)的iOS當(dāng)中的那個(gè)核心運(yùn)動(dòng)框架CoreMotion蜂挪。

1. 陀螺儀介紹

陀螺儀主要是用來(lái)測(cè)量沿著某個(gè)特定的坐標(biāo)軸旋轉(zhuǎn)速度的。在使用中嗓化,陀螺儀始終指向一個(gè)固定的方向棠涮,當(dāng)運(yùn)動(dòng)物體的運(yùn)動(dòng)方向偏離預(yù)定方向時(shí),陀螺儀就可以感受出來(lái)刺覆。

在手機(jī)上严肪,僅用加速度計(jì)沒(méi)辦法測(cè)量或重構(gòu)出完整的3D動(dòng)作,測(cè)不到轉(zhuǎn)動(dòng)的動(dòng)作的谦屑,加速計(jì)只能檢測(cè)軸向的線性動(dòng)作驳糯。但陀螺儀則可以對(duì)轉(zhuǎn)動(dòng)、偏轉(zhuǎn)的動(dòng)作做很好的測(cè)量伦仍,這樣就可以精確分析判斷出使用者的實(shí)際動(dòng)作结窘。而后根據(jù)動(dòng)作,可以對(duì)手機(jī)做相應(yīng)的操作充蓝。

1.1 陀螺儀的應(yīng)用場(chǎng)景

各位童鞋相比都玩過(guò)Wii,那個(gè)體感手柄肯定就用到了陀螺儀。玩家通過(guò)揮動(dòng)運(yùn)動(dòng)手柄谓苟,來(lái)控制游戲官脓。例如乒乓球、網(wǎng)球涝焙、賽車(chē)等等卑笨。有一些酷炫的APP會(huì)通過(guò)小幅度的傾斜,偏轉(zhuǎn)手機(jī)仑撞,實(shí)現(xiàn)彩蛋功能赤兴,例如放大縮小之類(lèi)的∷硐或者把手機(jī)屏幕翻轉(zhuǎn)桶良,就可以拒接電話或者靜音啥的。 拍照類(lèi)的APP也會(huì)通過(guò)陀螺儀把拍照時(shí)候手的抖動(dòng)反饋交給圖像處理器沮翔,以便抓到更清晰穩(wěn)定的圖片陨帆。

還有一些是最近剛剛看到的好賤好賤的APP。例如Send Me To Heaven采蚀,游戲的玩法超級(jí)簡(jiǎn)單疲牵,只需向天空拋擲手機(jī),扔得越高榆鼠,分?jǐn)?shù)也就越高纲爸。

Throw Me App 另外一個(gè)賤不拉幾的APP。這是一個(gè)相機(jī)APP妆够,使用時(shí)打開(kāi)APP并將手機(jī)拋向空中识啦,當(dāng)手機(jī)在空中時(shí),使用陀螺儀和加速計(jì)探測(cè)手機(jī)是否達(dá)到了最高點(diǎn)责静,且攝像頭是否向下袁滥。隨后,該應(yīng)用將激活攝像頭快門(mén)進(jìn)行拍照灾螃。

1.2 陀螺儀在iOS中的使用

iPhone题翻、iPad、iWatch都有內(nèi)置的陀螺儀腰鬼,也都可以讓開(kāi)發(fā)者進(jìn)行調(diào)用嵌赠。同樣,用一張圖展現(xiàn)一下:

2. 陀螺儀的使用

2.1 使用步驟

陀螺儀同樣也是通過(guò)CoreMotion這個(gè)框架來(lái)管理的熄赡,所以和加速計(jì)一樣姜挺,四個(gè)標(biāo)準(zhǔn)步驟:

初始化CMMotionManager管理對(duì)象;

調(diào)用管理對(duì)象的對(duì)象方法獲取數(shù)據(jù)彼硫;

處理數(shù)據(jù)炊豪;

當(dāng)不需要使用的時(shí)候凌箕,停止獲取數(shù)據(jù)。

2.2 陀螺儀數(shù)據(jù)獲取的兩種方法

CoreMotion中有2種獲取數(shù)據(jù)方式词渤,一種叫做PUSH的方式牵舱,一種叫做PULL的方式。顧名思義缺虐,PUSH就是被動(dòng)的獲取芜壁。設(shè)定完了之后,線程定時(shí)把獲取到的數(shù)據(jù)推送回來(lái)高氮』弁可想而知,對(duì)于資源的消耗是會(huì)稍微大一點(diǎn)的剪芍。 PULL塞淹,就是要去索取。拉一下才會(huì)獲取到數(shù)據(jù)紊浩。不要不給窖铡。上一次加速計(jì)咱們給出的代碼是OC的,今天咱們就用Swift的坊谁。

2.2.1 PULL的方式

privatefunc?useGyroPull()?{

//判斷陀螺儀可不可用

ifmanager.isGyroAvailable?{

//設(shè)置陀螺儀多久采樣一次

manager.gyroUpdateInterval?=0.1

//開(kāi)始更新费彼,后臺(tái)線程開(kāi)始運(yùn)行。這是Pull方式口芍。

manager.startGyroUpdates()

}

//獲取并處理陀螺儀數(shù)據(jù)箍铲。這里我們就只是簡(jiǎn)單的做了打印。

print("X?=?\(manager.gyroData?.rotationRate.x????0)","Y?=?\(manager.gyroData?.rotationRate.y????0)","Z?=?\(manager.gyroData?.rotationRate.z????0)")

}

2.2.2 PUSH的方式

privatefunc?useGyroPush()?{

//判斷陀螺儀可不可用

ifmanager.isGyroAvailable?{

//設(shè)置陀螺儀多久采樣一次

manager.gyroUpdateInterval?=0.1

//Push方式獲取和處理數(shù)據(jù)鬓椭,這里我們一樣只是做了簡(jiǎn)單的打印颠猴。把采樣的工作放在了主線程中。?????????????????????manager.startGyroUpdates(to:?OperationQueue.main,?withHandler:?{?(gyroData,?error)?in

print("X?=?\(self.manager.gyroData?.rotationRate.x????0)","Y?=?\(self.manager.gyroData?.rotationRate.y????0)","Z?=?\(self.manager.gyroData?.rotationRate.z????0)")

})

}else{

print("陀螺儀不可用")

}

}

3. 開(kāi)始我們的小游戲

3.1 思維導(dǎo)圖

3.2 實(shí)現(xiàn)

3.2.1 以X軸邊界值處理及碰壁后速度處理為例

//????????????對(duì)球在X軸碰壁進(jìn)行處理

ifcurrentPoint.x?=?bounds.size.width?-?imageWidth?/2{

currentPoint.x?=?bounds.size.width?-?imageWidth?/2

ballXVelocity?=?-ballXVelocity?*0.8

}

3.2.2 開(kāi)啟陀螺儀并更新

manager.deviceMotionUpdateInterval?=1/60

//注意一下小染,在Swift沒(méi)有了NSOperation翘瓮。被OperationQueue取代了。

manager.startDeviceMotionUpdates(to:?OperationQueue.main)?{?(motion,?error)in

self.ballView!.accelleration?=?(motion?.gravity)!

//開(kāi)啟主隊(duì)列異步線程裤翩,更新球的位置资盅。

DispatchQueue.main.async?{

self.ballView!.updateLocation(multiplier:5000)

}

3.2.3 更新小球的位置

func?updateLocation(multiplier?:?Double)?{

if(lastUpdateTime?!=?nil)?{

let?updatePeriod?:?Double?=Date.init().timeIntervalSince(lastUpdateTime!)

ballXVelocity?=?ballXVelocity?+?accelleration.x?*?updatePeriod

ballYVelocity?=?ballYVelocity?+?accelleration.y?*?updatePeriod

let?coefficient?=?updatePeriod?*?multiplier

currentPoint?=?CGPoint(x:?currentPoint.x?+?(CGFloat)(ballXVelocity?*?coefficient),?y:?currentPoint.y?-?(CGFloat)(ballYVelocity?*?coefficient))

}

lastUpdateTime?=Date()

}

3.3 關(guān)于Swift中重寫(xiě)set/get

其實(shí)寫(xiě)到這里的時(shí)候才突然想起來(lái),咱們從來(lái)沒(méi)有說(shuō)過(guò)Swift怎么重寫(xiě)Set/Get方法踊赠。而且貌似也沒(méi)有分享過(guò)iOS開(kāi)發(fā)中多線程的東東呵扛。下個(gè)系列非典型技術(shù)宅就可以寫(xiě)寫(xiě)多線程相關(guān)的玩意兒吧,如果多線程這部分不太明白的話筐带,對(duì)不住對(duì)不住對(duì)不住今穿,馬上補(bǔ)上。

在swift中其實(shí)重寫(xiě)set不太常見(jiàn)伦籍,但這都是OC留下來(lái)的臭毛病蓝晒,就非要重新咋辦腮出?請(qǐng)自行搜索,就不提供鏈接到*書(shū)了拔创。

這個(gè)不是重點(diǎn)利诺,咱們?cè)趯?xiě)小球的時(shí)候用到的是didSet這個(gè)方法富蓄。這是啥吶剩燥?這是swift當(dāng)中的觀察者,用來(lái)監(jiān)視屬性除了初始化之外的屬性變化立倍。

didSet:在屬性值改變后觸發(fā)灭红,didSet可以帶一個(gè)oldName的參數(shù),表示舊的屬性口注,不帶的話默認(rèn)命名為oldValue变擒。

willSet:在屬性值改變前觸發(fā),可以帶一個(gè)newName的參數(shù)寝志,沒(méi)有的話娇斑,該參數(shù)默認(rèn)命名為newValue。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末材部,一起剝皮案震驚了整個(gè)濱河市毫缆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乐导,老刑警劉巖苦丁,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異物臂,居然都是意外死亡旺拉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)棵磷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蛾狗,“玉大人,你說(shuō)我怎么就攤上這事仪媒〕磷溃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵规丽,是天一觀的道長(zhǎng)蒲牧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赌莺,這世上最難降的妖魔是什么冰抢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮艘狭,結(jié)果婚禮上挎扰,老公的妹妹穿的比我還像新娘翠订。我一直安慰自己,他們只是感情好遵倦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布尽超。 她就那樣靜靜地躺著,像睡著了一般梧躺。 火紅的嫁衣襯著肌膚如雪似谁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天掠哥,我揣著相機(jī)與錄音巩踏,去河邊找鬼。 笑死续搀,一個(gè)胖子當(dāng)著我的面吹牛塞琼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播禁舷,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼彪杉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了牵咙?” 一聲冷哼從身側(cè)響起派近,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霜大,沒(méi)想到半個(gè)月后构哺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡战坤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年曙强,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片途茫。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碟嘴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出囊卜,到底是詐尸還是另有隱情娜扇,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布栅组,位于F島的核電站雀瓢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏玉掸。R本人自食惡果不足惜刃麸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望司浪。 院中可真熱鬧泊业,春花似錦把沼、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至篮奄,卻和暖如春捆愁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宦搬。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工牙瓢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人间校。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像页慷,于是被迫代替她去往敵國(guó)和親憔足。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容