在本人仍是學生的時候,flappyBird這款遊戲很是火爆,最後等到Android版的出來以後,也是很癡迷的玩了一把。但是,本人遊戲天賦一直平平,幾度玩得想摔手機。本文主要介紹如何開發iOS平臺的flappyBird,遊戲中使用了本來軟件的圖片資源,僅做學習交流使用。本人實現的flappyBird遊戲包含遊戲等級設定,排行榜,音效等功能。html
flappyBird是單機遊戲,主要涉及界面邏輯、圖片資源、遊戲動畫、得分排行。git
爲了實現這幾個功能,須要使用如下幾個技術框架:github
1)AVFoundationapp
2)歸檔框架
3)模態視圖dom
4)NSTimer佈局
5)視圖控件,包括UIImageView、UILabel、UITableView等學習
一、建立工程動畫
1)打開Xcode,點擊新建工程,選擇Single View Application模板spa
2)填寫工程信息
二、移除Main.storyboard文件
上圖是flappyBird的文件目錄,由於Xcode6使用模板建立工程時會自動生成Main.storyboard文件,而工程中本人使用代碼佈局,因此能夠移除Main.storyboard文件。具體操做方法能夠參看本人另外一篇文章:
三、遊戲界面佈局
1)主菜單界面,遊戲難度設定界面、排行榜界面,效果圖以下
2)遊戲界面,效果圖以下
須要說明的是,Game Over這個界面,首先須要隱藏或者等到遊戲結束才建立。本人是選擇在遊戲斷定結束時才建立並顯示。
四、遊戲運行
這款遊戲的兩個關鍵點:
1)使用定時器驅動遊戲界面運行,即遊戲界面中的柱子高低變化與柱子的消失與產生。
2)遊戲結束的斷定,這裏涉及兩個問題,一是碰撞檢測,二是計分統計。
一、計分統計
-(void)columnLabelClick { if (topPipeFrame.origin.x == (100 + 30 - 70)) { columnNumber++; columnLabel.text = [NSString stringWithFormat:@"%zi",columnNumber]; } }
二、繪製柱子
-(void)pipe { //通道高度 NSInteger tunnelHeight = 0; //根據遊戲難度設定通道高度 if([[DataTool stringForKey:kRateKey] isEqualToString:@"ordinary"]) { tunnelHeight = 100; }else if([[DataTool stringForKey:kRateKey] isEqualToString:@"general"]) { tunnelHeight = 90; }else if([[DataTool stringForKey:kRateKey] isEqualToString:@"difficult"]) { tunnelHeight = 80; }else if([[DataTool stringForKey:kRateKey] isEqualToString:@"hard"]) { tunnelHeight = 75; } else if([[DataTool stringForKey:kRateKey] isEqualToString:@"crazy"]) { tunnelHeight = 70; } //柱子圖像 NSInteger tall = arc4random() % 200 + 40; topPipe = [[UIImageView alloc]initWithFrame:CGRectMake(320, -20, 70, tall)]; topPipe.image = [UIImage imageNamed:@"pipe"]; [self.view addSubview:topPipe]; bottomPipe = [[UIImageView alloc]initWithFrame:CGRectMake(320, tall + tunnelHeight, 70, 400)]; bottomPipe.image = [UIImage imageNamed:@"pipe"]; [self.view addSubview:bottomPipe]; //把底部圖片視圖放在柱子視圖上面 [self.view insertSubview:roadView aboveSubview:bottomPipe]; }
三、使用定時器,驅動遊戲界面運行,並進行碰撞檢測
//添加定時器 timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(onTimer) userInfo:nil repeats:YES]; //定時器操做 -(void)onTimer { //底部動畫移動 CGRect frame = roadView.frame; if (frame.origin.x == -15) { frame.origin.x = 0; } frame.origin.x--; roadView.frame = frame; //上升 if (isTap == NO) { CGRect frame = birdsView.frame; frame.origin.y -= 3; number += 3; birdsView.frame = frame; if (number >= 60) { isTap = YES; } } //降低 if(isTap == YES && birdsView.frame.origin.y < 370){ CGRect frame = birdsView.frame; frame.origin.y++; number -= 2; birdsView.frame = frame; number = 0; } //柱子移動 topPipeFrame = topPipe.frame; CGRect bottomPipeFrame = bottomPipe.frame; topPipeFrame.origin.x--; bottomPipeFrame.origin.x--; topPipe.frame = topPipeFrame; bottomPipe.frame = bottomPipeFrame; if (topPipeFrame.origin.x < -70) { [self pipe]; } //碰撞檢測(交集) bool topRet = CGRectIntersectsRect(birdsView.frame, topPipe.frame); bool bottomRet = CGRectIntersectsRect(birdsView.frame, bottomPipe.frame); if (topRet == true || bottomRet == true) { [self.soundTool playSoundByFileName:@"punch"]; [self onStop]; } if (topPipeFrame.origin.x == (100 + 30 - 70)) { [self.soundTool playSoundByFileName:@"pipe"]; [self columnLabelClick]; } }
四、更新分數,更新最佳分數與排行榜分數,並使用歸檔將數據持久化
-(void)updateScore { //更新最佳成績 if (columnNumber > [DataTool integerForKey:kBestScoreKey]) { [DataTool setInteger:columnNumber forKey:kBestScoreKey]; } //更新本局分數 [DataTool setInteger:columnNumber forKey:kCurrentScoreKey]; //更新排行榜 NSArray *ranks = (NSArray *)[DataTool objectForKey:kRankKey]; NSMutableArray *newRanksM = [NSMutableArray array]; NSInteger count = ranks.count; BOOL isUpdate = NO; for (NSInteger i = 0; i < count; i++) { NSString *scoreStr = ranks[i]; NSInteger score = [scoreStr integerValue]; if (score < columnNumber && isUpdate == NO) { scoreStr = [NSString stringWithFormat:@"%zi", columnNumber]; [newRanksM addObject:scoreStr]; isUpdate = YES; i--; } else { scoreStr = [NSString stringWithFormat:@"%zi", score]; [newRanksM addObject:scoreStr]; } } if (newRanksM.count > count) { [newRanksM removeLastObject]; } [DataTool setObject:newRanksM forKey:kRankKey]; }
五、繪製GameOver提示顯示
-(void)pullGameOver { //遊戲結束操做界面 gameOver = [[GameOverView alloc] initWithFrame:CGRectMake(20, 160, 280, 300)]; gameOver.delegate = self; [self.view addSubview:gameOver]; }
六、遊戲中止操做
-(void)onStop { //更新分數 [self updateScore]; //中止定時器 [timer setFireDate:[NSDate distantFuture]]; //彈出遊戲結束操做界面 [self pullGameOver]; }
這款遊戲的實現仍是很簡單的,主要使用UIImageView自帶的動畫實現方式,便可實現bird的動畫效果。使用NSTimer便可實現遊戲場景的柱子移動,至於柱子的高度,則可使用隨機數方式在必定範圍內實現高低變化。最後可使用CGRectIntersectsRect來實現邊界碰撞檢測來斷定遊戲是否結束。
以上是本人開發iOS版flappyBird的簡要過程介紹,其中只包含了關鍵點的代碼實現,具體完整遊戲源代碼地址:https://github.com/CharsDavy/flappyBird
【掃描關注更多幹貨】
公衆號:xiaoniu