博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS学习之flappyBird游戏的实现
阅读量:6297 次
发布时间:2019-06-22

本文共 5143 字,大约阅读时间需要 17 分钟。

导言

在本人还是学生的时候,flappyBird这款游戏非常火爆,最后等到Android版的出来之后,也是很痴迷的玩了一把。可是,本人游戏天赋一直平平,几度玩得想摔手机。本文主要介绍如何开发iOS平台的flappyBird,游戏中使用了原本软件的图片资源,仅作学习交流使用。本人实现的flappyBird游戏包含游戏等级设定,排行榜,音效等功能。

技术点

flappyBird是单机游戏,主要涉及界面逻辑、图片资源、游戏动画、得分排行。

为了实现这几个功能,需要使用以下几个技术框架:

1)AVFoundation

2)归档

3)模态视图

4)NSTimer

5)视图控件,包括UIImageView、UILabel、UITableView等

实现过程

1、创建工程

1)打开Xcode,点击新建工程,选择Single View Application模板

 

2)填写工程信息

 2、移除Main.storyboard文件

上图是flappyBird的文件目录,因为Xcode6使用模板创建工程时会自动生成Main.storyboard文件,而工程中本人使用代码布局,所以可以移除Main.storyboard文件。具体操作方法可以参看本人另一篇文章:

3、游戏界面布局

1)主菜单界面,游戏难度设定界面、排行榜界面,效果图如下

        

2)游戏界面,效果图如下

需要说明的是,Game Over这个界面,首先需要隐藏或者等到游戏结束才创建。本人是选择在游戏判定结束时才创建并显示。

4、游戏运行

这款游戏的两个关键点:

1)使用定时器驱动游戏界面运行,即游戏界面中的柱子高低变化与柱子的消失与产生。

2)游戏结束的判定,这里涉及两个问题,一是碰撞检测,二是计分统计。

具体实现部分代码

1、计分统计

-(void)columnLabelClick {        if (topPipeFrame.origin.x == (100 + 30 - 70)) {        columnNumber++;        columnLabel.text = [NSString stringWithFormat:@"%zi",columnNumber];    }}
2、绘制柱子

-(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];}
3、使用定时器,驱动游戏界面运行,并进行碰撞检测

//添加定时器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];    }}
4、更新分数,更新最佳分数与排行榜分数,并使用归档将数据持久化

-(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];}
5、绘制GameOver提示显示

-(void)pullGameOver {    //游戏结束操作界面    gameOver = [[GameOverView alloc] initWithFrame:CGRectMake(20, 160, 280, 300)];    gameOver.delegate = self;    [self.view addSubview:gameOver];}
6、游戏停止操作

-(void)onStop {    //更新分数    [self updateScore];    //停止定时器    [timer setFireDate:[NSDate distantFuture]];    //弹出游戏结束操作界面    [self pullGameOver];}

小结

这款游戏的实现还是很简单的,主要使用UIImageView自带的动画实现方式,即可实现bird的动画效果。使用NSTimer即可实现游戏场景的柱子移动,至于柱子的高度,则可以使用随机数方式在一定范围内实现高低变化。最后可以使用CGRectIntersectsRect来实现边界碰撞检测来判定游戏是否结束。

以上是本人开发iOS版flappyBird的简要过程介绍,其中只包含了关键点的代码实现,具体完整游戏源代码地址:

转载地址:http://qdqta.baihongyu.com/

你可能感兴趣的文章
OC实例变量和属性-@synthesize与@property
查看>>
MP3 编码解码 附完整c代码
查看>>
MVC匿名类传值学习
查看>>
POJ 3057 Evacuation(二分匹配)
查看>>
POJ - 2549 Sumsets
查看>>
《系统分析与设计方法》 计算投资回收分析
查看>>
客户端AJAX验证表单
查看>>
HTML框架,列表,表格
查看>>
UIButton设置 textAlignment 属性的方法
查看>>
4、NIO--通道的原理和获取
查看>>
解决js跨域调用WebApi的问题
查看>>
spring mvc 与Struts的认识
查看>>
如何高效的利用博客园?
查看>>
[Winform]检测exe是否已经运行,并将其置顶
查看>>
lync项目总结
查看>>
组合模式(Composite Pattern)
查看>>
[转载] 杜拉拉升职记——33 360度评估
查看>>
关于webrtc视频会议的解决方案
查看>>
开发检测MySQL主从同步插件
查看>>
[转]掌握Ajax 第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 [IBM]
查看>>