前言
分享:心诚求之,虽上中,上远矣,未有学养子而后嫁者也。
时钟动画:
又称逐帧动画,开发者需要逐帧计算每次屏幕刷新时的图像位置,相对性能较低,但是能够精确控制。iOS开发中时钟动画实现通常使用CADisplayLink。本飞机大战示例程序参考刘凡的演练实现。
飞机大战-效果演示
开发笔记
1. 开发之前,要确保开发代码的独立完整性,可以通过xcode提供的group的方式来实现,具体请看示例程序
2. 新建项目
1)新建 AirPlayGame 分组,保存游戏相关的所有代码和素材
2)新建images.bundle,将其拖拽至分组,并添加启动图片
3)设置游戏运行方向为纵向,取消状态栏
3. 加载资源视图和标题视图
1) 创建LoadingView
2) 创建TitleView
1> 使用游戏背景图片作为标题视图的背景
2> 在屏幕的中心位置显示Logo图片
3) 使用后台线程加载资源
4) 新建游戏视图控制器,在显示标题视图后一秒,自动进入游戏
4. 显示背景视图
1) 加载图片资源
2) 游戏模型对象,来管理背景图片的滚动位置
增加方法,向下移动游戏背景图片
3) 背景视图->背景图片
4) 实例化游戏模型和背景视图
5. 英雄战机
1) 加载图片资源
2) 游戏模型对象,管理英雄的位置以及其他...
3) 将英雄添加到游戏视图
4) 监听视图的touchMoved事件,更新英雄的模型数据中的位置
5) 在step方法中,更新英雄位置
6. 发射子弹
1) 加载图片资源
2) 游戏模型对象,部分存储在英雄模型中
3) 发射子弹fire,每次发射三颗,添加到bulletSet中
4) 控制器调用fire方法,真正发射子弹,每一颗子弹要建立一个UIImageView并添加到视图中
7. 子弹的后续处理
1) 每次时钟触发时,更新屏幕上所有子弹的位置,向屏幕上方移动
屏幕上的子弹数量与hero中的bulletSet中的子弹对象数量是上一致的
2) 如果子弹飞出屏幕,将子弹视图移除屏幕,从视图中删除(需要借助临时的set)
3) 如果hero中的bulletSet中包含子弹数据,新建UIImageView添加到视图中
关于集合数据的处理,需要注意:
在遍历集合的过程中,不能直接删除集合中的任何内容,要用临时集合处理。
8. 敌机出动
1) 加载敌机资源,三类敌机的大小、动画上完全相同
2) 建立敌机模型,传入敌机尺寸,以便计算敌机出现的随机位置
3) 建立敌机视图,传入enemy对象和imageRes(单例)简化视图建立
敌机视图中直接记录挨揍和爆炸的图像数组,以便后续处理
4) 扩展游戏模型,增加创建敌机方法,以便视图控制器调用
5) 在时钟方法中每秒创建3架小飞机,每隔10秒随机创建中飞机或者大飞机
9. 互殴——碰撞检测
1) 子弹击中敌机
用子弹的伤害值减敌机的生命值
1> 如果敌机的生命值小于等于0,敌机爆炸
2> 如果大于0,显示挨揍图片
问题1. 如何做碰撞检测?
使用CGRectIntersectsRect方法可以判断矩形是否相等
问题2. 当飞机的hp<=0时,如何播放飞机爆炸效果?
由于无法准确地知道序列帧动画何时完成,因此上能使用序列帧动画来播放飞机爆炸的效果
要解决此问题,可以通过逐帧播放来处理
在飞机模型中增加两个属性
1> toBlowup:需要播放爆炸序列帧标示
2> blowupFrames:爆炸序列图片当前播放帧数
如果帧数与爆炸数组中的总数相等,将飞机图片从视图和集合中删除
2) 敌机撞英雄
一下就死
检测完子弹和敌机碰撞之后,检测敌机和英雄的碰撞
遍历敌机集合,依次与英雄做碰撞检测,当出现碰撞时
播放英雄爆炸序列帧动画,动画完成后,调用方法关闭游戏时钟。
10. 界面扩展,增加暂停按钮和得分标签
1) 增加游戏视图,作为游戏的容器视图,以方便游戏界面的调整
2) 添加暂停按钮,通过按钮的tag判断游戏的运行状态,从而修改按钮显示图标,并且开启或关闭时钟
3) 添加得分标签,在model中,添加score属性,飞机摧毁时,修改游戏得分
11. 音效和背景音乐——没有音乐的游戏,是难以想象的!
1) 导入AVFoundation和AudioToolBox框架
2) 音效是使用C语言函数加载的
特点:短,直接播放,上允许中断
如果重夊建立,会生成多个SystemSoundId
结语
本示例程序有大量注释,主要思想是我们老生常谈的MVC。复习一下飞机大战示例程序地址。