生活随笔
收集整理的這篇文章主要介紹了
ios加速计(可以用来检测摇动,自定义反应灵敏度)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ios加速計???????? 標簽:?ios?編程?xcode開發?加速計?雜談???分類:?ios開發?? ?內置加速計是iPhone和iPod?Touch中最酷的特性之一,iPhone可以通過這個小設備知道用戶握持手機的方式,以及用戶是否移動了手機。iPhoneOS使用加速計處理自動旋轉,并且許多游戲都使用他做為控制機制。它還可以用于檢測搖動和其他突發的運動。?? ?? ?加速計物理學?? 通過感知特定方向的慣性力總量,加速計可以測量出加速度和重力。iPhone內的加速計是一個三軸加速計,這意味著他能夠檢測到三維空間中的運動或重力引力。因此,加速計不但可以指示握持電話的方式(如自動旋轉功能),而且如果電話放在桌子上的話,還可以指示電話的正面朝下還是朝上。?? 加速計可以測量g引力,因此加速計返回值為1.0時,表示在特定方向上感知到1g。如果是靜止握持iPhone而沒有任何運動,那么地球引力對其施加的力大約為1g。如果是縱向豎直地握持iPhone,那么iPhone會檢測并報告其y軸上施加的力大約為1g。如果是以一定角度握持iPhone,那么1g的力會分布到不同的軸上,這取決于握持iPhone的方式。在以45度角握持時,1g的力會均勻地分解到兩個軸上。?? ?? 如果檢測到的加速計值遠大于1g,那么即可以判斷這是突然運動。正常使用時,加速計在任一軸上都不會檢測到遠大于1g的值。如果搖動、墜落或投擲iPhone,那么加速計便會在一個或多個軸上檢測到很大的力。?? iPhone加速計使用的三軸結構是:iPhone長邊的左右是X軸(右為正),短邊的上下是Y軸(上為正),垂直于iPhone的是Z軸(正面為正)。需要注意的是,加速計對y坐標軸使用了更標準的慣例,即y軸伸長表示向上的力,這與Quartz?2D的坐標系相反。如果加速計使用Quartz?2D做為控制機制,那么必須要轉換y坐標軸。使用OpenGL?ES時則不需要轉換。?? ?? ?訪問加速計?? UIAccelerometer類是單獨存在的。要獲取對此類的引用,請調用sharedAccelerometer方法:?? ?? UIAccelerometer?*accelerometer=[UIAccelerometer?sharedAccelerometer];?? ?? 從加速計獲取信息與從Core?Location獲取信息相似。創建一個符合UIAccelerometerDelegate協議的類,執行可以獲取加速計信息的方法。?? 在分配委托時,需要以秒指定更新間隔。iPhone的加速計支持最高以每秒100次的頻率進行輪詢,但無法保證真正達到這么多次更新,或者可以精確均勻分隔這些更新。要分配委托或指定輪詢間隔為每秒60次,可以如下所示:?? ?? accelerometer.delegate=self;?? accelerometer.updateInterval=1.0f/60.0f;?? ?? 完成之后,剩余的事情是實現加速計用于更新委托的方法,accelerometer:didAccelerate:。第二個變量包含了來自加速計的真實數據,嵌入在類UIAcceleration的一個對象中。?? ?? ?UIAcceleration?? 如前所述,iPhone加速計可以檢測3個軸上的加速度,并且對使用UIAcceleration類實例的委托提供此信息。每個UIAcceleration實例都有x、y和z的屬性,分別有一個帶符號的浮點值。值0表示加速計在此軸上沒有檢測到任何運動。正值或負值表示一個方向上的力。例如,y的負值表示感受到了向下的力,這可能表示電話是縱向豎直握持的。y的正值表示在向上的方向施加了某些力,這可能意味著電話是倒置的或者電話正在向下運動。(這里有點疑問?說反了吧?)?? 請在頭腦中牢記圖15-1的示意圖,并查看加速計結果。注意,在現實生活中,幾乎不可能獲得如此精確的值,因為加速計非常敏感,可以感知非常微笑的運動,而我們通常只能感知立體空間3個軸上的某一個微小受力。這是現實世界中的物理,而不是高中物理實驗室。?? ?? ?實現accelerometer:didAccelertae:方法?? ?? -?(void)accelerometer:(UIAccelerometer?*)accelerometer?didAccelerate:(UIAcceleration?*)acceleration?{?? NSString?*newText=[[NSString?alloc]?initWithFormat:@"Max:?x:?%g\ty:%g\tz:?? ?? %g",acceleration.x,acceleration.y,acceleration.z];?? label.text=newText;?? [newText?release];?? }?? ?? 此方法可以在每次調用時更改界面上的標簽,調用此方法的頻率取決于以前指定的updateInterval的值。?? ?? 1,檢測搖動?? 加速計通常用于檢測搖動。與手勢相似,搖動可以作為應用程序輸入的一種形式。例如,對于繪圖程序GLPaint,iPhone的示例代碼之一,用戶可以通過搖動iPhone擦除繪圖,就像Etch-a-Sketch一樣。搖動檢測功能相對來說是微不足道的,主需要檢查某個軸上的絕對值是否大于閾值(yu)。在正常使用期間,3個軸之一所注冊的值通常在1.3g左右,若要遠高于此值,則需要刻意施加力量。加速計好像不能注冊高于2.3g左右的值。因此,請勿將閾值設置得高于此值。?? ?? 要檢測搖動,請檢查絕對值是否大于1.5(表示輕微搖動)和2.0(表示劇烈搖動),代碼如下:?? ?? -?(void)accelerometer:(UIAccelerometer?*)accelerometer?didAccelerate:(UIAcceleration?*)acceleration?{?? if?(fbasf(acceleration.x)>2.0?||?fbasf(acceleration.y)>2.0?||?fbasf(acceleration.z)>2.0?)?{?? ?? }?? }?? ?? 上述方法可以檢測到任一軸上任何超過2g力的運動。通過要求用戶前后搖動一定次數才能注冊為一次搖動,我們可以執行更復雜的搖動檢測,代碼如下:?? ?? -?(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?(fbasf(acceleration.x)>2.0?||?fbasf(acceleration.y)>2.0?||?fbasf(acceleration.z)>2.0?)?{?? shakeCount++;?? if?(shakeCount>4)?{?? ?? shakeCount=0;?? [shakeStart?release];?? shakeStart=[[NSDate?alloc]?init];?? }?? }?? }?? ?? 此方法可以查明加速計報告的值大于2的次數,如果在1.5s的時間內發送了4次,則注冊為一次搖動。?? ?? ?? 2.加速計用作方向控制器?? 或許加速計在第三方應用程序中最常見的用法是作為游戲控制器。在游戲中不是使用按鈕控制字符或對象的移動,而是使用加速計。例如,在賽車游戲中,像轉動方向盤那樣轉到iPhone也許就可以駕駛汽車,而向前傾斜表示加速,向后傾斜表示剎車。?? 具體如何將加速計用作控制器,這很大程度上取決于游戲的特定機制。在很簡單的情況下,可能只需要獲取一個軸的值,乘以某個數,然后添加到所控制對象的坐標系中。?? 使用加速計作為控制器的一個棘手問題是,委托方法并不能保證以指定的間隔回調。如果告訴加速計每秒鐘更新60次委托類,所能確定的僅僅是他每秒鐘更新的次數絕對不會多于60次。因此不能保證每秒鐘得到60次均勻分隔的更新,所以如果所做的動畫是基于來自加速計的輸入,那么必須要弄清楚委托方法調用之間的時間。?? ?? 說明?本章中的應用程序在仿真器上不起作用,因為仿真器中沒有加速計。?? ?? 搖動與擊碎?? 我們要編寫一個應用程序,他在檢測到搖動之后會使電話看起來和聽起來好像他因為搖動而破碎一樣。啟動此應用程序后,程序會顯示一張圖片,他看起來像是iPhone的首頁。?? 搖動電話時,發出破碎的聲音,并更換圖片。?? 然后只需觸摸屏幕,就可以重置其初始狀態。?? ?? ?用于擊碎的代碼?? 創建一個基于視圖的項目?ShakeAndBreak。在?15?ShakeAndBreak文件夾中找到兩張圖像和一個聲音文件,拖到Resources文件夾中。還有一個icon.png,也添加到Resources文件夾。?? 展開Resources文件夾中的info.plist,在屬性列表中添加一個條目,告訴應用程序不要使用狀態欄。單擊Information?Property?List行,單擊出現在本行末端的按鈕,添加一個新的子值,將新行的Key改為UIStatusBarHidden,然后在右鍵單擊剛才添加的行的空Value列。此時應該出現一個上下文菜單,選擇ValueType為Boolean。此行應該變為一個復選框,單擊選中此復選框。最后,修改Icon?File為icon.png。?? ?? 然后,展開Classes文件,單擊ShakeAndBreakViewController.h:?? ?? #define?kAccelerationThreshold?2.2?? #define?kUpdateInterval?(1.0f/10.0f)?? ?? #import?<AudioToolbox/AudioToolbox.h>?? ?? @interface?ShakeAndBreakViewController:UIViewController?<UIAccelerometerDelegate>?{?? IBOutlet?UIImageView?*imageView;?? BOOL?brokenScreenShowing;?? SystemSoundId?soundID;?? UIImage?*fixed;?? UIIMage?*broken;?? }?? @property?..?? @end?? ?? 我們定義更新頻率為1s?10次,這已經足夠檢測到一次搖動。通常來說,輪詢時會使用能滿足要求的最低頻率。在將加速計用作控制器時,需要以相當快的速率輪詢,通常達到每秒30次到60次更新。?? ?? 打開ShakeAndBreakViewController.xib。單擊View圖標,Cmd+3?修改其大小,高度460=》480,將Image?View從庫中拖到View窗口中。?? ?? 單擊ShakeAndBreakViewController.m:?? ?? -?(void)viewDidLoad?{?? UIAccelerometer?*accel=[UIAccelerometer?sharedAccelerometer];?? accel.delegate=self;?? accel.updateInterval=kUpdateInterval;?? ?? NSString?*path=[[NSBundle?mainBundle]?pathForResource:@"glass"?ofType:@"wav"];?? AudioServicesCreateSystemSoundID((CFURLRef)[NSURL?fileURLWithPath:path],&soundID);?? ?? self.fixed=[UIImage?imageNamed:@"home.png"];?? self.broken=[UIImage?imageNamed:@"homebroken.png"];?? ?? imageView.image=fixed;?? brokenScreenShowing=NO;?? }?? ?? -?(void)accelerometer:(UIAccelerometer?*)accelerometer?didAccelerate:(UIAcceleration?*)acceleration?{?? if?(!?brokenScreenShowing)?{?? if?(acceleration.x?>kAccelerationThreshold?||?acceleration.y?>kAccelerationThreshold?||?acceleration.z?? ?? >kAccelerationThreshold)?{?? imageView.image=broken;?? AudioServicePlaySystemSound(soundID);?? brokenScreenShowing=YES;?? }?? }?? }?? -?(void)touchesBegan:(NSSet?*)touches?withEvent:(UIEvent?*)event?? {?? imageView.image=fixed;?? brokenScreenShowing=NO;?? }?? @end?? ?? ?? 滾彈珠程序?? 我們的下一個小游戲,是通過傾斜電話在iPhone的屏幕上移動彈珠。此處,我們使用Quartz?2D來處理動畫。在處理游戲或其他需要平滑動畫的程序時,通常的規則是使用OpenGL。這里使用Quartz?2D是因為他比較簡單。?? ?? 使用基于視圖的模版創建一個新項目?Ball。在15?Ball文件夾中,找到ball.png,將其添加到Resources文件夾中。?? 然后單擊Classes文件夾,Cmd+N新建UIView?subClass,命名為BallView.m。?? ?? 雙擊BallViewController.xib,單擊View圖標,將視圖的類改為BallView,將視圖的背景顏色改為黑色,然后重新設置File's?Owner的view輸出口為BallView。?? ?? ?實現BallView控制器?? 單擊BallViewController.h:?? ?? #define?kUpdateInterval?(1.0f/60.0f)?? ?? @interface?BallViewController:UIViewController?<UIAccelerometerDelegate>?{?? }?? @end?? ?? 轉到BallViewController.m:?? ?? -?(void)viewDidLoad?{?? UIAccelerometer?*accel=[UIAccelerometer?sharedAccelerometer];?? accel.delegate=self;?? accel.updateInterval=kUpdateInterval;?? [super?viewDidLoad];?? }?? ?? -?(void)accelerometer:(UIAccelerometer?*)accelerometer?didAccelerate:(UIAcceleration?*)acceleration?{?? [(BallView?*)self.view?setAcceleration:acceleration];?? [(BallView?*)self.view?draw];?? }?? ?? ?編寫Ball?View?? 單擊BallView.h:?? ?? #define?kVelocityMultiplier?500?? ?? @interface?BallView:UIView?{?? UIImage?*image;?? CGPoint?currentPoint;?? CGPoint?previousPoint;?? ?? UIAcceleration?*acceleration;?? CGFloat?ballXVelocity;?? CGFloat?ballYVelocity;?? }?? -?(void)draw;?? @end?? ?? 切換到BallView.m:?? ?? -?(id)initWithCoder:(NSCoder?*)coder?{?? if?(self=[super?initWithCoder:coder])?{?? self.image=[UIIMage?imageNamed:@"ball.png"];?? self.currentPoint=CGPointMake((self.bounds.size.width/2.0f)+(image.size.width?/?2.0f),(self.bounds.size.height/2.0f)+(image.size.height?/?2.0f));?? ?? ballXVelocity=0.0f;?? ballYVelocity=0.0f;?? }?? return?self;?? }?? ?? -?(void)drawRect:(CGRect)?rect?{?? [image?drawAtPoint:currentPoint];?? }?? ?? -?(CGPoint)currentPoint?{?? return?currentPoint;?? }?? ?? -?(void)setCurrentPoint:(CGPoint)newPoint?{?? previousPoint=currentPoint;?? currentPoint=newPoint;?? ?? if?(currentPoint.x<0)?{?? currentPoint.x=0;?? ballXVelocity=0;?? }?? ?? if?(currentPoint.y<0)?{?? currentPoint.y=0;?? ballYVelocity=0;?? }?? ?? if?(currentPoint.x?>?self.bounds.size.width?-image.size.width?)?{?? currentPoint.x=self.bounds.size.width?-image.size.width;?? ballXVelocity=0;?? }?? ?? if?(currentPoint.y?>?self.bounds.size.height?-image.size.height?)?{?? currentPoint.y=self.bounds.size.height?-image.size.height;?? ballYVelocity=0;?? }?? ?? CGRect?currentImageRect=CGRectMake(currentPoint.x,currentPoint.y,currentPoint.x+image.size.width,currentPoint.y+image.size.height);?? CGRect?previousImageRect=CGRectMake(previousPoint.x,previousPoint.y,previousPoint.x+image.size.width,previousPoint.y+image.size.height);?? [self?setNeedsDisplayInRect:CGRectUnion(currentImageRect,previousImageRect)];?? }?? ?? -?(void)draw?{?? static?NSDate?*lastDrawTime;?? if?(lastDrawTime?!=nil)?{?? NSTimeInterval?secondsSinceLastDraw=-([lastDrawTime?timeIntervalSinceNow]);?? ?? ballYVelocity=ballYVelocity+-(acceleration.y?*secondsSinceLastDraw);?? ballXVelocity=ballXVelocity+(acceleration.x?*secondsSinceLastDraw);?? ?? CGFloat?xAcceleration=secondsSinceLastDraw?*ballXVelocity?*500;?? CGFloat?yAcceleration=secondsSinceLastDraw?*ballYVelocity?*500;?? ?? self.currentPoint?=?CGPointMake(self.currentPoint.x+xAcceleration,self.currentPoint.y+yAcceleration);?? }?? ?? [lastDrawTime?release];?? lastDrawTime=[[NSDate?alloc]?init];?? }?? ?? @end ?
總結
以上是生活随笔為你收集整理的ios加速计(可以用来检测摇动,自定义反应灵敏度)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。