分享
陀螺仪与方向感应器.pdf
下载文档

ID:3447423

大小:583.44KB

页数:15页

格式:PDF

时间:2024-05-02

收藏 分享赚钱
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,汇文网负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
网站客服:3074922707
陀螺仪 方向 感应器
陀螺儀和方向感應器 iPhone、iPad和iPod Touch最酷的一項功能是它們的內建方向感應器,這個微小的裝置可以讓iOS知道裝置被持握的方式以及是否在移動。iOS可使用方向感應器來處理自動旋轉,而許多遊戲也都使用它做為控制機制。此外它也可以用來偵測搖晃與突然的移動。17-1 方向感應器的物理原理 方向感應器(accelerometer)是藉由感應某個方向的慣性力大小來衡量其加速度與重力。iOS裝置內的方向感應器是一個三軸的方向感應器,表示它可以偵測三度空間中的移動或重力。因此讀者可以利用方向感應器得知裝置目前被握持的方式(像是自動旋轉功能),也可以得知它是否是平放在桌上,甚至可以知道是正面朝上還是正面朝下。方向感應器的度量單位為g力(g表示重力),所以當方向感應器傳回1.0的值時表示它在某個特定方向感應到了1g的力。底下有三個例子:?如果裝置拿在手上沒有移動,由於地心引力的關係,大約會有1g的作用力在它上面。?如果裝置是以直向且完全垂直的方式持握時,它會偵測並報告有1g的作用力在y軸上。?如果裝置是以某個角度持握時,則1g的力便會根據持握的方式而分散到不同的軸。當以45度角持握時,這1g的力會大約均分到兩個軸上。570 突然的移動則可以藉由檢查方向感應器的值是否比1g大很多來偵測。在正常的使用情況下,方向感應器在任何軸上所偵測到的都不會超過1g太多。但如果讀者搖晃、掉落或丟擲裝置,則方向感應器會在一個以上的軸上偵測到非常大的受力。不過請不要掉落或丟擲讀者自己的iOS裝置來測試這個理論。圖17-1以圖形表示方向感應器所使用的三個軸。請注意方向感應器使用的是較標準的y軸座標習慣用法,也就是y值增加表示向上的力,這剛好和第十四章中Quartz 2D的座標系統相反。當讀者使用方向感應器搭配Quartz 2D做為控制機制時,需要轉換y軸座標。但當搭配OpenGL ES時(比較可能發生在讀者使用方向感應器來控制動畫時),就不需要轉換。圖17-1:iPhone方向感應器的三維座標軸左邊的iPhone 4前視圖顯示了x和y軸。右邊的iPhone 4側視圖則顯示了z軸。陀螺儀和方向感應器 571 17-2 不要忘記旋轉 我們之前提過iPhone 4還有個陀螺儀感應器,可讓讀者讀取描述裝置繞著軸旋轉的值。如果此感應器和方向感應器之間的差異看起來不清楚的話,請想想平放在桌上的iPhone。假如讀者在該手機平放時開始旋轉它,方向感應器的值不會改變。這是因為移動手機的力量(在這裡只有沿著z軸向下拉的重力)並沒有改變。(實際上的情形則有一點點的不同,因為讀者手碰到手機的動作一定會觸發少量的方向感應器動作)。不過在相同動作的期間,裝置的旋轉值則會改變,特別是z軸的旋轉值。順時針旋轉裝置會產生負的值,逆時針旋轉則會提供正的值。停止轉動則z軸的旋轉值會回到零。陀螺儀會在裝置發生旋轉時通知讀者該項變更,而不是記錄一個絕對的旋轉值。讀者馬上就會在本章第一個範例中看到這是如何運作。17-3 Core Motion 和動作管理程式(motion manager)從iOS 4起,方向感應器和陀螺儀的值是使用Core Motion架構來存取。此架構提供的東西中包括了CMMotionManager此一類別,它可當成所有用來描述使用者如何移動裝置之值的方法。讀者的應用程式可建立CMMotionManager的實例,然後以下面的模式來利用它?它可以在一有動作發生時就為讀者執行某些程式碼。?它可以保持永久性的更新結構而讓讀者可以在任何時間存取最新的值。後面一種方法很適合遊戲及其他高度互動的應用程式,因為它們需要在每次通過遊戲迴圈時查詢裝置的目前狀態。我們將告訴讀者如何實作這二種方式。請注意CMMotionManager類別實際上不是單一實例,但讀者的應用程式應該把它當成是來對待。讀者應該使用正常的alloc和init方法在應用程式中建立唯一的一個CMMotionManager類別。所以如果讀者需要從應用程式中的好幾個地方來存取動作管理程式時,應該在應用程式委派中建立它並提供從委派存取它的權利。除了CMMotionManager類別外,Core Motion還提供了幾個其他的類別,像是CMAccelermeterData和CMGryoData,它們只是容器,讀者的應用程式可透過它們來存取動作資料。我們在提到這些類別時會加以說明。572 事件型動作(event-based motion)我們之前提過動作管理程式的一種運作模式是每次動作資料改變時就為讀者執行某些程式碼。大多數其他的Cocoa Touch類別,都是藉由讓讀者連接到這時候會取得訊息的委派,來提供這種功能,但Core Motion的方式則有一點不同。因為它是個新的架構,只有在iOS 4之後才有,所以Apple決定讓CMMotionManager使用iOS 4 SDK的另一項新功能,也就是區塊(block)。我們在本書中已經使用過數次區塊,現在讀者將看到此技巧的另一種應用。請使用Xcode來建立一個名為MotionMonitor的檢視型應用程式新專案。這會是個可讀取方向感應器資料和陀螺儀資料(有的話)並在螢幕上加以顯示的簡單應用程式。本章中的應用程式無法在模擬器上運作,因為模擬器沒有方向感應器也沒有陀螺儀。噢,真遜。首先我們需要將Core Motion連結到我們的應用程式。因為這是個選用的系統架構,所以我們必須將它加入。請按照第七章增加音訊工具箱架構(在音訊工具箱架構中的連結一節)的說明,但不要選取AudioToolbox.framework而是選取CoreMotion.frmaework。(總言之,請按住control鍵再點按Frameworks資料夾,並從出現的內容選單中選取AddExisting Frameworks.。)現在請選取MotionMonitorViewController.h檔並做下列變更:#import#import interface MotionMonitorViewController:UIViewController CMMotionManager*motionManager;UILabel*accelerometerLabel;UILabel*gyroscopeLabel;property(nonatomic,retain)CMMotionManager*motionManager;property(nonatomic,retain)IBOutlet UILabel*accelerometerLabel;property(nonatomic,retain)IBOutlet UILabel*gyroscopeLabel;end 這會提供我們一個存取動作管理程式本身的指標,以及一對到顯示資訊之標籤的接口。這裡不太需要解釋,所以請繼續並儲存讀者的變更。接著在Interface Builder中開啟MotionMonitorViewController.xib。陀螺儀和方向感應器 573 在此nib視窗中連按二下其圖示來開啟檢視,然後從程式庫中拖拉出一個標籤到此檢視中。調整標籤的大小以讓它從左邊的藍色指引線跑到右邊的藍色指引線,高度則為整個檢視的一半,然後將標籤的頂端對齊上面的藍色指引線。現在開啟屬性項檢閱器並將#Lines欄位從1改成0。#Lines屬性項是用來指定標籤上會出現幾行文字,並可提供嚴格的上限。但如果讀者將它設為0,則沒有限制可用,所以標籤有多少行都可以。接著請按住option鍵再拖拉該標籤已建立一個複本,並將此複本對齊檢視下半部中的藍色指引線。最 後 請 按 住control鍵 再 從Files Owner圖 示 拖 拉 到 各 個 標 籤,將accelerometerLabel和gyroscopeLabel分別連接到上下二個標籤。這個簡單的GUI已經完成了,請儲存讀者的工作並準備好進行編碼。接著請選取MotionMonitorViewController.m並將屬性合成器(synthesizer)增加至實作區塊的頂端,將記憶體管理呼叫增加到viewDidUnload和dealloc方法的底部:#import MotionMonitorViewController.h implementation MotionMonitorViewController synthesize motionManager;synthesize accelerometerLabel;synthesize gyroscopeLabel;.-(void)viewDidUnload /Release any retained subviews of the main view./e.g.self.myOutlet=nil;self.motionManager=nil;self.accelerometerLabel=nil;self.gyroscopeLabel=nil;super viewDidUnload;-(void)dealloc motionManager release;accelerometerLabel release;gyroscopeLabel release;super dealloc;end 現在比較有趣的部分來了。請移除viewDidLoad方法周圍的註解標記並給它下列的內容:-(void)viewDidLoad super viewDidLoad;574 self.motionManager=CMMotionManager alloc init autorelease;NSOperationQueue*queue=NSOperationQueue alloc init autorelease;if(motionManager.accelerometerAvailable)motionManager.accelerometerUpdateInterval=1.0/10.0;motionManager startAccelerometerUpdatesToQueue:queue withHandler:(CMAccelerometerData*accelerometerData,NSError*error)NSString*labelText;if(error)motionManager stopAccelerometerUpdates;labelText=NSString stringWithFormat:Accelerometer encountered error:%,error;else labelText=NSString stringWithFormat:Accelerometern-nx:%+.2fny:%+.2fnz:%+.2f,accelerometerData.acceleration.x,accelerometerData.acceleration.y,accelerometerData.acceleration.z;accelerometerLabel performSelectorOnMainThread:selector(setText:)withObject:labelText waitUntilDone:YES;else accelerometerLabel.text=This device has no accelerometer.;if(motionManager.gyroAvailable)motionManager.gyroUpdateInterval=1.0/10.0;motionManager startGyroUpdatesToQueue:queue withHandler:(CMGyroData*gyroData,NSError*error)NSString*labelText;if(error)motionManager stopGyroUpdates;labelText=NSString stringWithFormat:Gyroscope encountered error:%,error;else labelText=NSString stringWithFormat:Gyroscopen-nx:%+.2fny:%+.2fnz:%+.2f,gyroData.rotationRate.x,gyroData.rotationRate.y,gyroData.rotationRate.z;gyroscopeLabel performSelectorOnMainThread:selector(setText:)withObject:labelText waitUntilDone:YES;else gyroscopeLabel.text=This device has no gyroscope;此方法包含了啟動感應器所需的全部程式碼,並告訴它們每1/10秒就向我們報告一次並同時更新螢幕畫面。陀螺儀和方向感應器 575 感謝區塊的強大功能,讓一切都變得簡單又緊密。現在不用將功能部分放入委派方法中,區塊中定義的行為就可讓我們在設定行為的同一個方法中看見該行為!讓我們一次處理一小部分。就從底下的先開始:self.motionManager=CMMotionManager alloc init autorelease;NSOperationQueue*queue=NSOperationQueue alloc init autorelease;此程式碼首先建立了一個CMMotionManager的實例,我們將會使用它來觀察動作事件。然後它又建立了一個作業佇列,它只是一堆需要完成之工作的容器,讀者可以回想第十三章一下。動作管理程式想要有一個佇列來放置要完成的工作,並依讀者給它的區塊所指定,每次發生一個事件。使用系統的預設佇列來做這件事是很誘人的,但CMMotionManager的說明文件明白地警告不要這麼做!因為擔心預設佇列最後塞滿了這些事件,而導致在處理其他重要的系統事件時會有困難。接著進行到設定方向感應器。我們先檢查以確認裝置真得有方向感應器。目前上市的所有手持iOS裝置都有,但為防未來可能有的會沒有,所以還是值得檢查一下。接著我們設定更新之間的時間間隔,並以秒為單位來指定。這裡我們要求的是1/10秒。請注意這麼設定並不一定保證我們會接收到速度如此精準的更新。事實上,該項設定其實是個上限,只是指定動作管理程式可以提供給我們的最佳速率。實際上的更新可能沒這麼頻繁。if(motionManager.accelerometerAvailable)motionManager.accelerometerUpdateInterval=1.0/10.0;接著我們告訴動作管理程式開始報告方向感應器的更新。我們傳入了一個讓動作管理程式放置工作的佇列,以及一個定義工作會在每次更新發生時完成的區塊。請記住,區塊都是從插入符號()開始,後面再接著以括號包起來的一串引數,這些引數是區塊執行時要去填入的(在此例中,是方向感應器的資料和警告我們有問題的錯誤),最後再以內有要執行之程式碼的大括號區段作結尾。motionManager startAccelerometerUpdatesToQueue:queue withHandler:(CMAccelerometerData*accelerometerData,NSError*error)底下是區塊的內容。它會根據目前方向感應器的值建立一個字串,或是如果有問題的話則產生一個錯誤訊息。然後它會將該字串值推入accelermeterLabel中。這裡我們不能直接這麼做,因為像UILable等的UIKit類別通常只有在從主執行緒中存取時才會運作順利。由於這段程式碼是從NSOperationQueue內執行,所以我們不知道將會在哪個特定佇列中執行。因此我們使用performSelectorOnMainThread:withObject:waitUntilDone:方法以讓主執行緒處理此工作。576 請注意方向感應器的值是透過傳入之accelerometerData的acceleration屬性來存取。Acceleration屬性是CMAcceleration類型,該類型只是個包含了三個float值的簡單struct。accelerometerData本身是個CMAccelerometer類別的實例,而該類別其實只是CMAcceleration的包裝函式(wrapper)而已!如果讀者認為只為了傳送三個float而使用了這麼多類別好像是沒必要的話,那麼不是只有讀者會這麼想。不管如何,底下是它的使用方式:NSString*labelText;if(error)motionManager stopAccelerometerUpdates;labelText=NSString stringWithFormat:Accelerometer encountered error:%,error;else labelText=NSString stringWithFormat:Accelerometern-nx:%+.2fny:%+.2fnz:%+.2f,accelerometerData.acceleration.x,accelerometerData.acceleration.y,accelerometerData.acceleration.z;accelerometerLabel performSelectorOnMainThread:selector(setText:)withObject:labelText waitUntilDone:YES;接著我們結束此區塊,並結束一開始傳入此區塊所在之方括號方法呼叫。最後我們提供完全不同的程式碼路徑,以防裝置沒有方向感應器。如前所述,目前所有的iOS裝置都有方向感應器,但誰知道未來會是怎樣呢?;else accelerometerLabel.text=This device has no accelerometer.;讀者可能注意到陀螺儀的程式碼在結構上完全相同,不同的只是哪些方法會被呼叫以及如何存取所報告的值。由於太類似了所以這裡不需要逐一為讀者解釋。現在請在讀者現有的iOS裝置上建立和執行此應用程式,並試試它(見圖17-2)。當讀者將裝置傾斜不同的方向時,會看到方向感應器的值會隨著方向不同而調整,而只要讀者穩穩地拿住裝置,該值也會保持穩定。陀螺儀和方向感應器 577 圖17-2:在iPhone 4上執行的MotionMonitor。不幸地,如果讀者在模擬器上執行此應用程式時將會看到一對錯誤訊息。如果讀者有iPhone 4(若將來任何有陀螺儀的裝置),會看到這些值如何改變。每當裝置定住不動時,不管是在哪個方向,陀螺儀的值都會在零附近徘徊。不過當讀者旋轉它時,會看到陀螺儀的值如何依據讀者的旋轉而改變。當讀者停止移動裝置時,這個值都會回到零。主動式動作存取 讀者已經看過在動作發生時如何藉由傳送要呼叫的CMMotionManager區塊來存取動作資料。這種由事件驅動的動作處理足夠應付一般的Cocoa應用程式,但有時候它不太符合應用程式的特定需求。舉例來說,互動式遊戲通常有個一直在執行的迴圈來處理使用者輸入、更新遊戲狀態和重繪螢幕畫面。在這種情況下,由事件驅動的方式就不怎麼適合,因為讀者需要去實作一個等待動作事件的物件、在收到感應器最近的位置時加以記錄並準備在需要時將該資料回報給主要的遊戲迴圈。好在CMMotionManager有個內建的解決方案。現在不用將區塊傳入,只要使用startAccelerometerUpdates和startGytoUpdates二方法去告訴區塊啟用感應器,之後任何時間想要的話,只要直接從動作管理程式讀取數值就好了。578 讓我們使用此方式來改變我們的MotionMonitor應用程式,以讓讀者可以看看它是如何運作。一開始請先製作讀者MotionMonitor專案資料夾的複本。接著增加一個新的實例變數和比對(matching)屬性到MotionMonitorViewController.h,和一個指向NSTimer的指標,此NSTimer將會觸發我們所有顯示的更新:#import#import interface MotionMonitorViewController:UIViewController CMMotionManager*motionManager;UILabel*accelerometerLabel;UILabel*gyroscopeLabel;NSTimer*updateTimer;property(retain)CMMotionManager*motionManager;property(retain)IBOutlet UILabel*accelerometerLabel;property(retain)IBOutlet UILabel*gyroscopeLabel;property(retain)NSTimer*updateTimer;end 現在請切換到MotionMonitorViewController.m,讀者需要在這裡合成此新屬性,並在dealloc中釋放它:implementation MotionMonitorViewController synthesize motionManager;synthesize accelerometerLabel;synthesize gyroscopeLabel;synthesize updateTimer;.-(void)dealloc motionManager release;accelerometerLabel release;gyroscopeLabel release;updateTimer release;super dealloc;刪除我們之前有的整個viewDidLoad方法,並以底下較簡單的版本來取代,此版本只是設置此動作管理程式並提供資訊性的標籤給欠缺感應器的裝置:-(void)viewDidLoad super viewDidLoad;self.motionManager=CMMotionManager alloc init autorelease;陀螺儀和方向感應器 579 if(motionManager.accelerometerAvailable)motionManager.accelerometerUpdateInterval=1.0/10.0;motionManager startAccelerometerUpdates;else accelerometerLabel.text=This device has no accelerometer.;if(motionManager.gyroAvailable)motionManager.gyroUpdateInterval=1.0/10.0;motionManager startGyroUpdates;else gyroscopeLabel.text=This device has no gyroscope.;一般而言,我們會使用viewDidLoad和viewDidUnload將有關GUI顯示之屬性的建立與摧毀加上括號。不過在我們新計時器的情形中,我們想要它只在更小的時間視窗內啟用,也就是實際顯示該檢視時。以這種方式我們可以將主要遊戲迴圈的使用量維持在最小。我們可藉由像底下一樣地實作viewWillAppear:和viewDidDisappear:來完成此事。請將這二個方法增加到viewDidLoad後:-(void)viewWillAppear:(BOOL)animated super viewWillAppear:animated;self.updateTimer=NSTimer scheduledTimerWithTimeInterval:1.0/10.0 target:self selector:selector(updateDisplay)userInfo:nil repeats:YES;-(void)viewDidDisappear:(BOOL)animated super viewDidDisappear:animated;self.updateTimer=nil;viewWillAppear:中的程式碼會建立一個新的計時器,並排定它每1/10秒就啟動一次去呼叫updateDisplay方法,但這個方法我們還沒建立。請將此方法增加到viewDidDisappear底下:-(void)updateDisplay if(motionManager.accelerometerAvailable)CMAccelerometerData*accelerometerData=motionManager.accelerometerData;accelerometerLabel.text=NSString stringWithFormat:Accelerometern-nx:%+.2fny:%+.2fnz:%+.2f,accelerometerData.acceleration.x,accelerometerData.acceleration.y,accelerometerData.acceleration.z;580 if(motionManager.gyroAvailable)CMGyroData*gyroData=motionManager.gyroData;gyroscopeLabel.text=NSString stringWithFormat:Gyroscopen-nx:%+.2fny:%+.2fnz:%+.2f,gyroData.rotationRate.x,gyroData.rotationRate.y,gyroData.rotationRate.z;請在讀者的裝置上建立並執行此應用程式,讀者應該會看到它的行為和第一版的一模一樣。現在讀者已經看過二種存取動作資料的方式。請使用最適合的給讀者的應用程式。方向感應器的結果 我們之前提過iPhone的方向感應器可偵測三個軸上的加速度,而且它可使用CMAcceleration struct來提供此資訊。每個CMAcceleration都有x、y和z欄位,而每個欄位都存放一個浮點值。0的值表示方向感應器在該軸上沒有偵測到移動。正或負的值則表示在某方向上有受力。舉例來說,y值為負表示感應到向下的拉力,因此可能代表是以直向模式垂直拿著手機。y值為正則表在相反的方向上有作用力,這可能表示手機是顛倒拿或是向下移動。請記住圖17-3中的圖表,並讓我們看一下部分的方向感應器結果。請注意,在真實生活中,讀者不太可能會得到這麼精確的值,因為方向感應器很靈敏,即使一點點動作都讀得到,所以讀者通常在三個軸上都至少讀得到一丁點的力。這是真實生活中的物理現象而不是課堂中的物理現象。在第三方應用程式中最常見的方向感應器使用方式或許是做為遊戲的控制器。本章稍後我們將建立一個使用方向感應器做為輸入的程式,但首先讓我們看另一個常見的方向感應器使用:偵測搖晃。陀螺儀和方向感應器 581 圖17-3:不同裝置方向的理想化加速度值 17-4 偵測搖晃 搖晃和手勢動作一樣,也可以當成應用程式的一種輸入形式。舉例來說,iOS範例程式碼專案中的繪圖程式GLPaint,它讓使用者可以藉由搖晃iOS裝置的方式來擦掉繪製的圖形。偵測搖晃的情形非常簡單,只需要檢查某一個軸上的絕對值是否大於設定的門檻。在正常的使用情況下,三個軸之中有一個軸紀錄高達1.3 g的值並非少見,但要得到比這還要高出許多的值則通常需要故意施力。方向感應器似乎無法記錄超過2.3 g以上的值(至少我們的經驗是如此),所以不要將門檻設得比這還要高。要偵測搖晃情況,讀者可以使用像底下的程式碼來檢查絕對值,大於1.5的為輕微搖晃,大於2.0的則為強力搖晃:582-(void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration if(fabsf(acceleration.x)2.0|fabsf(acceleration.y)2.0|fabsf(acceleration.z)2.0)/Do something here.上述方法可以偵測到任何軸上任何超過二倍重力的動作。讀者也可以藉由要求使用者來回搖晃一定次數後才將此動作紀錄為搖晃,從而實作更精密的搖晃偵測,其程式碼如下:-(void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration static NSInteger shakeCount=0;static NSDate*shakeStart;NSDate*now=NSDate alloc init;NSDate*checkDate=NSDate alloc initWithTimeInterval:1.5f sinceDate:shakeStart;if(now compare:checkDate=NSOrderedDescending|shakeStart=nil)shakeCount=0;shakeStart release;shakeStart=NSDate alloc init;now release;checkDate release;if(fabsf(acceleration.x)2.0|fabsf(acceleration.y)2.0|fabsf(2.0.z)2.0)shakeCount+;if(shakeCount 4)/Do something shakeCount=0;shakeStart release;shakeStart=NSDate alloc init;這個方法會記錄方向感應器回報值超過2.0的次數,如果在1.5秒中有四次以上,它就將其記錄為搖晃。內建的搖晃 偵測搖晃實際上還有另外一種方式,也就是潛藏在回應程式鏈中的方式。還記得我們在第十五章中如何實作像touchesBegan:withEvent:等方法來偵測觸碰嗎?iOS也提供三個類似的回應程式方法來偵測動作:陀螺儀和方向感應器 583?當動作開始進行時,motionBegan:withEvent:方法會如第十五章中所討論過的先被傳送到第一回應程式然後在回應程式鏈上一路傳下去。?當動作結束時,motionEnded:withEvent:方法會被傳送到第一回應程式。?如 果 在 搖 晃 期 間,手 機 鈴 響 或 發 生 其 他 動 作 而 導 致 中 斷 時,motionCancelled:withEvent:訊息會傳送到第一回應程式。這表示不用直接使用CMMotionManager也可以偵測搖晃。讀者只要覆寫檢視或檢視控制器中適當的動作感應方法即可,然後當使用者搖晃手機時便會自動呼叫這些方法。除非讀者真得有需要對搖晃的手勢有更多種的控制方式,不然應該使用這些內建好的動作偵測方法,而不要使用本章介紹的手動方法,不過我們還是會將這種手動方法介紹一下,以防讀者萬一需要進行更多的控制。現在讀者已經對如何偵測搖晃有了基本的概念,我們接著將打壞讀者的手機。搖到壞 我們不是真的要搖壞讀者的手機,只是要寫一個能夠偵測搖晃的應用程式,然後讓讀者的手機看起來和聽起來像是被搖晃搖到壞了。當讀者啟動這個應用程式時,螢幕上應該會顯示如圖17-4所示的iPhone主畫面。如果將手機用力搖晃,讀者可憐的手機便會發出像是被搖壞的聲音,而且螢幕會出現如圖17-5所示的樣子。為什麼我們要做這麼邪惡的事?不用擔心,讀者可藉由碰觸螢幕來將iPhone重設回原來清純的樣貌。

此文档下载收益归作者所有

下载文档
收起
展开