导言

在本人还是学生的时候,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文件。具体操作方法可以参看本人另一篇文章:

《iOS学习之移除Main.storyboard》

3、游戏界面布局

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

        

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

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

4、游戏运行

这款游戏的两个关键点:

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

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

具体实现部分代码

1、计分统计

-(void)columnLabelClick {

    if (topPipeFrame.origin.x == ( +  - )) {
columnNumber++;
columnLabel.text = [NSString stringWithFormat:@"%zi",columnNumber];
}
}

2、绘制柱子

-(void)pipe {
//通道高度
NSInteger tunnelHeight = ;
//根据游戏难度设定通道高度
if([[DataTool stringForKey:kRateKey] isEqualToString:@"ordinary"]) {
tunnelHeight = ;
}else if([[DataTool stringForKey:kRateKey] isEqualToString:@"general"]) {
tunnelHeight = ;
}else if([[DataTool stringForKey:kRateKey] isEqualToString:@"difficult"]) {
tunnelHeight = ;
}else if([[DataTool stringForKey:kRateKey] isEqualToString:@"hard"]) {
tunnelHeight = ;
} else if([[DataTool stringForKey:kRateKey] isEqualToString:@"crazy"]) {
tunnelHeight = ;
} //柱子图像
NSInteger tall = arc4random() % + ; topPipe = [[UIImageView alloc]initWithFrame:CGRectMake(, -, , tall)];
topPipe.image = [UIImage imageNamed:@"pipe"];
[self.view addSubview:topPipe]; bottomPipe = [[UIImageView alloc]initWithFrame:CGRectMake(, tall + tunnelHeight, , )];
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 == -) {
frame.origin.x = ;
}
frame.origin.x--;
roadView.frame = frame; //上升
if (isTap == NO) {
CGRect frame = birdsView.frame;
frame.origin.y -= ;
number += ;
birdsView.frame = frame;
if (number >= ) {
isTap = YES;
}
} //下降
if(isTap == YES && birdsView.frame.origin.y < ){
CGRect frame = birdsView.frame;
frame.origin.y++;
number -= ;
birdsView.frame = frame;
number = ;
} //柱子移动
topPipeFrame = topPipe.frame;
CGRect bottomPipeFrame = bottomPipe.frame;
topPipeFrame.origin.x--;
bottomPipeFrame.origin.x--;
topPipe.frame = topPipeFrame;
bottomPipe.frame = bottomPipeFrame;
if (topPipeFrame.origin.x < -) {
[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 == ( + - )) {
[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 = ; 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(, , , )];
gameOver.delegate = self;
[self.view addSubview:gameOver];
}

6、游戏停止操作

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

小结

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

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

【扫描关注更多干货】

公众号:xiaoniu

iOS学习之flappyBird游戏的实现的更多相关文章

  1. 基于Keras的OpenAI-gym强化学习的车杆/FlappyBird游戏

    强化学习 课程:Q-Learning强化学习(李宏毅).深度强化学习 强化学习是一种允许你创造能从环境中交互学习的AI Agent的机器学习算法,其通过试错来学习.如上图所示,大脑代表AI Agent ...

  2. iOS学习路线图

    一.iOS学习路线图   二.iOS学习路线图--视频篇       阶 段 学完后目标 知识点 配套学习资源(笔记+源码+PPT) 密码 基础阶段 学习周期:24天       学习后目标:    ...

  3. iOS 学习资源

    这份学习资料是为 iOS 初学者所准备的, 旨在帮助 iOS 初学者们快速找到适合自己的学习资料, 节省他们搜索资料的时间, 使他们更好的规划好自己的 iOS 学习路线, 更快的入门, 更准确的定位的 ...

  4. iOS学习资源个人整理

    1208更新: http://www.tuyiyi.com                                    图翼网 https://github.com/Alamofire/Al ...

  5. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  6. iOS学习笔记总结整理

    来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...

  7. ios学习资料(一)

    IT社区: http://www.cnblogs.com/ http://www.csdn.net/ http://www.51cto.com/ http://www.cocoachina.com/ ...

  8. iOS学习资料整理

    视频教程(英文) 视频 简介 Developing iOS 7 Apps for iPhone and iPad 斯坦福开放教程之一, 课程主要讲解了一些 iOS 开发工具和 API 以及 iOS S ...

  9. iOS 学习

    iOS 学习资料 (适合初学者) 本文资料来源于GitHub 一.视频教程(英文) Developing iOS 7 Apps for iPhone and iPad斯坦福开放教程之一, 课程主要讲解 ...

随机推荐

  1. 纪念伟大的sb错-noip滚粗

    人弱就是弱,被sb错虐翻. 手一抖一生就毁了 开此博文纪念这个伟大的sb错! noip2014 d2t2逆bfs后删点手残没考虑后效性,完美爆80 愿省选rp++,求进noi,orz

  2. 关于js中遍历总结

    1.for循环 var arr = []; for (var i = 0; i < arr.length; i++) { if (条件1) return; if (条件2) break; if ...

  3. HTTP报文-->MVC

    引用 学习Web开发不好好学习HTTP报文,将会“打拳不练功,到老一场空”,你花在犯迷糊上的时间比你沉下心来学习HTTP的时间肯定会多很多. HTTP请求报文解剖 HTTP请求报文由3部分组成(请求行 ...

  4. VC++ 设置桌面壁纸

    Windows Shell API提供了接口IActiveDesktop来完成墙纸的设置. //IActiveDesktop 接口方法表 (详情参见MSDN) AddDesktopItem AddDe ...

  5. 一道money计算题引发的思考

    网友提出一个问题如下 是小学和中学时候学到了增长折线问题,有点像数学问题,不过这个要求用编程来实现,恐怕还是有些逻辑要处理的,话不多说看代码吧 我给出的代码如下 代码清单: <?php func ...

  6. iOS 开发之--使用AFNetWorking3.1.0上传单张/多张图片

    在调试接口的时候,遇到一个问题,就是多张图片上传的时候,不管我上传多少张,只会上传成功最后一张,也就是说只有一张图片上传成功了,针对这个问题,通过查找资料,找到了原因,首先,在上传的过程中,我们获取到 ...

  7. ios mrc & arc 并用

    如果在arc工程中倒入mrc文件就会提示出错. 解决办法如下: 在targets的build phases选项下Compile Sources下选择要使用arc编译的文件,双击它,输入-fno-obj ...

  8. nginx于tomcat项目整合(拆分静态文件)

    1.在很多时候我们在网站上应用的时候都会用到nginx,由于我们是java开发者,不可避免的是我们需要在我们的tomcat的工程中应用到nginx,这里的应用可以是请求转发,负载均衡,反向代理,配置虚 ...

  9. 170324、Spring 处理器和Resource

    1.Spring 框架允许开发者使用两种后处理器扩展 IoC 容器,这两种后处理器扩展 IoC 容器,这两种后处理器可以后处理 IoC 容器本身,或对容器中所有的 Bean 进行后处理.IoC 容器还 ...

  10. 160422、Highcharts后台获取数据

    而我这次做的是趋势图,涉及到动态刷新,做的过程还是花了一番功夫的,也补充和巩固了一点js的知识,为了纪念,把过程记录一下: 首先,是引入HIghcharts绘图相关的js文件和jQuery.js. 接 ...