1) 是否遇到障碍物。
2) 是否被敌方炮弹击中。
以上两种判断都涉及到游戏中一个十分重要的概念:碰撞探测(Collision detection)。本章将在前一章的基础之上,讲解主教精灵如何在地图中漫游,如何实现碰撞探测,如何通过火炮击中敌人。并且给出简单的敌方AI模拟。总之,完成本章学习之后,读者已经可以开始编写类似于“坦克大战”等基本简单游戏了。
下图就是我们示例ZYG007的游戏画面:
游戏的架构
游戏的编程模型
在正式详述示例之前,我们首先就游戏的整体编程模型进行一个简单的概述。每一个游戏都是所谓的现实模拟系统:按照预先规定的频率,将虚拟世界的状态不断的输出到目标屏幕上(每秒多少帧本质上就是每秒重画画面多少次),实现虚拟世界的模拟展示。用户的输入、内部定时器触发的各种程序逻辑通过修改内存变量进而修改虚拟世界的状态实现虚拟世界的运动、场景变化。如下图:
如上图所示,图像引擎按照每秒30次的频率不断将内存数据所描绘的虚拟世界画到iPhone的屏幕上,这就是所谓的30帧/秒。
通常情况下由以下3类独立的程序逻辑组成了游戏程序的主要编程模型。他们的共同点就是在不断修改内存数据:
1)
2)
3)
以上为游戏的主要内部架构,是我们理解游戏编程的基础。这与我们通常的面向功能的软件编程有很大的区别。与此对应的是游戏程序的调试很难按照通常的单步执行来找Bug的,通常要通过对游戏的运行日志分析来发现问题。
Cocos2d-iphone的编程模型
1) 内存数据。
CocosNode是最基础的数据单元,通过AddChild函数实现的互相联系起来的CocosNode派生类的实例组成了整个游戏的整体内存数据集合。还记得教程2中的下图么?
每一个场景就代表了当前画面虚拟的游戏世界,不同的场景通过Director对象切换完成整个游戏的各个关卡变化。每一个场景中的所有内容都是由精灵对象都是CocosNode的派生类的实例。
2) 更新引擎。
我们进一步细化之前的那个图:
那个按照预定频率不断更新画面的引擎就是Director对象,Director对象实现该引擎功能包括以下两个核心内容:
a)
从0.8.2开始,cocos2d-iphone开始支持4种形式的Director工作模式,这4重模式的核心不同点就是如何调用mainLoop函数:
l
l
l
l
无论以上那种工作模式,mainLoop被按照一定的间隔不断被调用这一基本模式是不变的。CCDirectorTypeNSTimer为默认工作模式,考虑到手持设备的电池问题,在游戏对实时性要求不是很高的情况下,建议大家维持使用默认方式,本章示例就是采用的默认方式。
b)
mainLoop函数主要做了以下两件事:
l
关键的调用语句:[[CCScheduler sharedScheduler] tick: dt];
对Cocos2d-iPhone源代码的分下表明,凡是通过类似以下语句来实现动作效果的定时处理逻辑,这里是整个机制的调用点:
[self schedule:@selector(KeepDoing) interval: 1/30];
Cocos2d-iPhone内置的各类动作的执行者 ActionManager就是使用该机制实现动画的。
l
关键的调用语句:[runningScene_ visit];
该函数将导致,所有的CocosNode派生类实例对象的draw函数将按照父子层级关系被逐一调用,这样就实现了全部游戏画面的展示。
3) 玩家指令
就是我们在第5章中讲的“触摸”事件处理机制。
4) 定时器
都是通过每一个CocosNode的schedule方法来实现的,而该方法内置的单例sharedScheduler就是前面讲的[[Scheduler sharedScheduler] tick: dt]的调用对象。至此,我们可以看出无论读者在Cocos2d中设置多少定时回调逻辑,其实并没有增加系统整体开销。所有的定时调用逻辑,无论是系统的Action还是游戏开发的逻辑最终都是在统一的调用中实现的:Scheduler 类的tick方法。
1) Cocos2d-iPhone提供不同的更新实现机制:NSTimer和While循环。
2) mainLoop函数确保:
a)
b)
因此,读取内存数据绘制画面与更新内存数据程序之间,各种不同的基于定时器(schedule)的更新内存数据的程序之间都是线性被调用执行的,不存在内存冲突。而且在每一个定时逻辑的具体处理时间点上,完全可以按照大家都是静止的来处理,也就是说不存在同时变化的任何内存对象。对于内存对象状态的修改都是线续排队执行的。
3) 我们可以放心的使用Cocos2d-iPhone提供的各种动作和效果,他们完全可以与我们的特定逻辑程序友好共处,因为大家的共同基础都是一样的。不要直接使用NSTimer和自己的定时器等。
...
如果您对本文感兴趣,可以到这里下载完整PDF。示例源代码下载。