各位读者老爷大家好,由于最近一直比较忙没什么空,导致好久没有更新文章了,明天有一天假期,就利用今晚时间和大家聊聊最近刚写的一个小游戏,由于自己的时间比较少,所以没有在细节上做过多的处理,程序还有很多不足的地方,也欢迎大家多多指出或者提出自己的观点,游戏代码仍然会在文章结尾处下载,废话不多说,进入正题。
Flappy Bird当年红极一时的小游戏,想必大家应该都玩过,先上一张效果图
我写游戏仍然按照自己的一贯风格,用最简单的代码或者逻辑实现游戏的主要功能,因为我的文章主要面向广大新手,加上自己也是一个初学者,主要目的是为了和大家交流经验。
接下来说一下游戏的几个主要功能是如何实现的:
第一步:游戏中的各种动画的实现 用到的知识:CADisplayLink定时器,以及控件的frame变化
这里不得不说说我时如何在在storyboard中搭建我的游戏界面的
我用到的游戏素材分别是小鸟,上方管子,下方管子,地面背景,城市草地背景
后面的天空背景是我自己设置的view的背景色
游戏中看着是小鸟在往右飞,其实我设置的是鸟只是在上下移动,而背景图片在不停往左移动,那么我是如何实现的背景图片在移动呢。
看我的搭建结构,大家可以看到我在view中又放了两个UIView控件,分别是view1和view2,view1的尺寸和屏幕一样,view2则在view1的右边紧紧挨着,也就是说在屏幕外面暂时看不到,然后两个都设置了背景颜色,以及地面背景图,城市草地背景图,我能够让游戏中的背景一直不停移动原理就是view1和view2以相同速度左移,当view1完全移出屏幕的时候,让它的frame变到view2的正右方,当view2移出屏幕的时候就让其frame变到view1的正右方,所以这样就能用两个view实现背景的无缝移动。
鸟和管道我都没有放到view1和view2中,而是都放到了原有的view中,为的是不让鸟和view1,view2一起移动,管子的话倒是无所谓,个人喜好吧。
同理,管子也要以和view1,view2一样的速度左移,从而实现一起移动的视觉效果。
注意CADisplayLink的方法大概是每秒调用60次,所以方法中每次控件移动的距离设的尽量小一点,这样不会导致速度移动过快。
说完了背景以及管道的移动再说下小鸟的,小鸟是要一直让它的frame的y值一直增加就能实现下降效果,点击屏幕鸟的位置向上移动的效果在touchesBegan方法里让它y值每次增加一些就可以实现。
还有就是鸟扇动翅膀的效果,就是两个图片不停的切换而已,动画效果差不多就这么多了
第二步:死亡条件判定
第一种情况是鸟掉道地上,这种比较简单,只要鸟的y值加上本身的height大于或等于地面背景的y值就可以判断
第二种死亡则是鸟碰到管子上,这里稍微复杂一点点,就是一个简单的碰撞检测
以上方的管子为例,简单的说也就是鸟的区域只要和管子的区域有一点重合就算失败,不理解的话可以看看这一段代码
if (self.redButton.x + BirdWH >= self.greenView.x && self.redButton.x <= CGRectGetMaxX(self.greenView.frame) && self.redButton.y <= CGRectGetMaxY(self.greenView.frame)) {
[self gameOver];
}
这个管子能明白的话,下方的管子也肯定能理解,这就是两种死亡条件
第三步: 如果让管子不停显示,并且长度不一
管子不停显示和view1,view2不停显示道理一样,就是一走出屏幕左边就让它的frame来到屏幕右边,至于长度则是每次来到屏幕右边的时候让它的height在一定范围内取个随机值,这样看起来就像好多不一样的管子了,为了追求难道,你们也可以增加管子的数量以及合理的设置随机长度范围,这里要注意,上方的管子只需要改变height就可以,但下方的height变化后它就不是长在地上的样子了,所以还要注意再根据随机长度修改y值,让管子的根一直扎在地上。
第四步: 分数显示
这里我遇到了一个bug,我一开始在view上放了个label控件准备显示分数,原理是每一个管子到达屏幕左边的时候让分数加1,然后每次分数变了的时候游戏就会刷新到开始的样子,我请教了一下后得知这里涉及到多线程那块的运行循环的知识,等我这里研究研究再来更新,bug没解决,我试了试手写代码产生label,这次没有出现错误,就先用手写的创建了。
游戏大体上基本就这样了,这和正版游戏的方法肯定有非常多不一样的地方,我只是利用有限的知识简单的实现了游戏的功能而已,大家有什么好的建议和想法,欢迎大家积极留言讨论。