ios CAAnimation動畫和SceneKit小遊戲
簡介
這篇主要介紹CAKeyframeAnimation關鍵幀動畫的使用,scenekit實現的飛機遊戲在下一篇詳細介紹。傳送門
先看看實現的動畫效果,下面在逐個分析。 git專案地址

總體效果圖.gif
動畫分析和實現
1. 搖錢樹

yqs.gif
這是我第一個app中的一個動畫,看到需求後一頭霧水,由於當時才接觸ios,簡直無從下手,經過各種百度後才找到一些頭緒。從監聽手機震動,到樹幹搖晃,最後掉落元寶,逐步理清了各個物件需要執行的行為動作。下面我會貼一些程式碼,具體的還請去專案中檢視,程式碼註釋也寫得很詳細。
手機搖晃監聽
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { NSLog(@"%@",NSStringFromSelector(_cmd)); } - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { NSLog(@"%@",NSStringFromSelector(_cmd)); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);//系統震動 [self ybAnimation]; [self shakeYQS:yqsImage]; }
搖晃樹幹
- (void)shakeYQS:(UIImageView *)view { //表示以z座標軸為中心軸旋轉 CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; animation.values = @[@(0),@(-M_PI_4/2),@(0),@(M_PI_4/2),@(0), @(-M_PI_4/3),@(0),@(M_PI_4/3),@(0), @(-M_PI_4/4),@(0),@(M_PI_4/4),@(0), @(-M_PI_4/5),@(0),@(M_PI_4/6),@(0)];//設定樹的搖晃幅度,分母變大表示搖晃幅度越來越小,不斷h衰減至0。 animation.repeatCount = 1; animation.duration = 1; [view.layer addAnimation:animation forKey:@"shake"]; }
這裡要理解keypath的意思,從程式碼中可以很直觀的看出監聽的是z軸旋轉屬性,判斷旋轉方向可以用握手定則,用手握住座標軸,大拇指指向座標軸方向,其餘四指為旋轉的方向,至於順逆時針,需要視情況而定。
至於元寶掉落,就是簡單的一個平移動畫
//元寶掉落 - (void)ybAnimation { for (int i = 0; i< ybArray.count; i++) { UIImageView * yb = ybArray[i]; int x = rand()%215; int y = rand()%60 + 60; yb.frame = CGRectMake(x + MinX(yqsImage), y + MinY(yqsImage), yb.frame.size.width, yb.frame.size.height); yb.hidden = NO; CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"]; animation.delegate = self; animation.values = @[@(yb.frame.origin.y), @(yb.frame.origin.y+200)]; float startTime = 0; animation.repeatCount = 1; float endTime = (float)(arc4random()%100) / 100 + 0.5; animation.keyTimes = @[@(startTime), @(endTime)]; animation.duration = endTime; animation.fillMode = kCAFillModeForwards; animation.removedOnCompletion = NO; [animation setValue:@"ybDrop" forKey:@"ybAnimation"]; [animation setValue:yb forKey:@"animationView"]; [yb.layer addAnimation:animation forKey:@"ybAnimation"]; } }
其實拿到一個動畫需求後,首先要理清的就是整個動畫過程中,每個物件執行了哪些行為。分析好後,然後就往基本動畫上套就行了,比如,平移,縮放,旋轉這些,再複雜點可能會加入路徑,3D場景變換等等,當然這些也需要一定的知識積累。下面兩個簡單動畫,我就不貼程式碼了,只寫一些分析思路。
2. 唱片動畫

recordCD.gif
從圖中知道,唱針和唱片執行的都是旋轉動畫,不同在於,唱針只旋轉了幾十度,而唱片卻是旋轉的360度,然後一直迴圈執行。
3. 閃爍動畫

flashing.gif
這裡中間的頭像在不斷放大縮小,明顯頭像執行的是縮放動畫。然後使用了貝塞爾曲線畫了兩個圈,一個靜止,另一個在執行一個組合動畫,即在擴大過程中,顏色逐漸變淡。這裡我模仿的是抖音直播時,頭像的閃爍動畫。
4. 扇形統計圖

sectorChart.gif
這個稍微複雜一點,從畫出扇形,到動畫執行,最後計算每個扇形的點選範圍並做出偏移。
首先,使用UIBezierPath和CAShapeLayer,畫出扇形。光畫出來還是比較簡單,然後是動畫執行。怎樣才會產生上圖那種類似掃描的效果?先來看看圓形進度條動畫

progress1.gif

progress2.gif
想象一下,如果把邊界的寬度一點點擴大達到圓的半徑的長度,是不是就會出現扇形圖掃描一樣的動畫了。
圖形畫好後,還要判斷點選範圍,這裡採用的數學公式計算。首先判斷該點是否在圓內,即點到圓心的距離是否大於半徑;然後是觸控點跟圓心連成的直線和起始邊形成的夾角是在哪個扇形區域類,都能通過公式計算出來。最後點選扇形執行偏移事件。(具體的計算公式請結合專案中的程式碼檢視理解)
5. 飛機遊戲
飛機遊戲的實現其實並不如想象中困難,主要基於SceneKit實現的,SceneKit中封裝了很多物件,使其從建立模型到執行動畫行為,操作起來都簡單易懂,感覺比較適合做一些小遊戲開發。我會在下一篇文章中寫出我的開發思路。
完結
感興趣的可以去專案地址下載下來看看。 git專案地址