iOS學習之flappyBird遊戲的實現

導言

在本人仍是學生的時候,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文件。具體操做方法能夠參看本人另外一篇文章:

《iOS學習之移除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

相關文章
相關標籤/搜索