游戏编程模式
为什么要读这本书:
- 抽象和解耦能够使你的程序开发变得更快和更简单。但不要浪费时间来做这件事,除非你确信存在问题的代码需要这种灵活性。
- 在你的开发周期中要对性能进行思考和设计,但是要推迟那些降低灵活性的,底层的,详尽的优化,能晚则晚。
- 尽快地探索你的游戏的设计空间,但是不要走得太快留下一个烂摊子给自己。
- 如果你将要删除代码,那么不要浪费时间将他整理的很整洁。
- 但是,最重要的是,若要做一些有意思的玩意,那就要乐在其中。
游戏编程模式内容:
分支:
设计模式
命令模式
在游戏中,命令行记录了玩家的一系列输入,并将之转换为游戏总的一个有意义的动作。这个过程常通过封装一个对象中的一个方法调用来实现。
在需要使用许多不同的命令类时,为了更容易的实现这些类,可以定义一个具体的基类,里面有一些使用的高层次的方法,这样便可以通过对派生出来的命令组合来定义其行为。
享元模式
享元模式一般在你有太多重复对象并考虑将其轻量化时派上用场。享元模式通过将对象数据切分成两种类型来解决问题。
第一种类型是那些不属于单一实例对象并且能够被所有对象共享的数据。GoF将其称为“内部状态”;
第二种类型是“外部状态”,对于每一个实例它们都是唯一的。
观察者模式
使用最为广泛的设计模式,C#在语言层面有“event”关键字,JAVA把它集成在了系统库(java.util.Observer)中。
观察者模式的未来:事件系统和其他类似的观察者的模式非常常见。但是,如果使用观察者模式来写大型的应用,就会出现一些问题。很多观察者的代码看起来差不多。通常看起来如下:
1.当一些状态改变的时候会收到通知。
2.修改部分UI来反应新的状态。
修改状态会导致工作重复和乏味,这时候需要使用“数据绑定(data binding)”。
原型模式
使用特定原型实例来创建特定种类的对象,并且通过拷贝原型来创建新的对象。
原型数据建模:一个通用的做法是使用JSON数据实体,一般都是字典或者属性集合。
但通常会出现大量的重复,所以给对象声明一个“prototype”属性,然后该属性指定另外一个对象。如果访问的任何属性不在此对象内部,那么会去它的原型对象里面查找。
例子:{
"name": "goblin grunt",
"minHealth": 20,
"maxHealth": 30,
"resists": ["cold", "posion"],
"weaknesses": ["fire", "light"]
}
{
"name": "goblin wizard",
"prototype": "goblin grunt",
"spells": ["fire ball", "lightning bolt"]
}
{
"name": "goblin archer",
"prototype": "goblin grunt",
"attacks": ["short bow"]
}
单例模式
确保一个类只有一个实例,并为其提供一个全局访问入口。这是需要避免使用的模式,它通常弊大于利。
如果要确保只实例化一次,只需要简单的使用静态类。
序列型模式
双缓冲
进行一系列序列化操作来表现出瞬发性或同步性。
OpenGL中的swapBuffer()函数,Direct3D中的“swapchains",微软XNA框架在endDraw()方法中也进行的帧缓冲区交换。
游戏循环
实现用户输入和处理器速度在游戏时间上的分离。
更新方式
通过对所有对象实例同时进行帧更新来模拟一系列相互独立的游戏对象。
行为模式
字节码
通过将行为编码成虚拟机指令,而使其具备数据的灵活性。
如何生成字节码
- 如果你定义了一种基于文本的语言:
- 你得定义一种语法。
- 你要实现一个分析器。
- 你必须处理语法错误。
- 对非技术人员没有亲和力。
- 如果你定义一个图形编辑工具:
- 你要实现一个用户界面。
- 不易出错。
- 可移植性差。
子类沙盒
使用一个基类的操作集合进而在子类中定义行为
类型对象
通过创建一个类来支持新类型的灵活创建,其每个实例都代表一个不同的对象类型。
解耦模式
当你掌握了一门语言,你会发现写代码来实现某个你想实现的功能是件相当容易的事情。难的是写出在此基础上容易添加或者更改功能的代码,因为我们几乎没有可能不更改程序的功能或特性。
- 组件将游戏的不同方面分离开却仍然具备它们的特性。
- 事件队列能够静态而且及时的将两个对象通信分离开。
- 服务定位器让代码能够访问到设备却不需要被绑定到提供服务的代码上。
组件模式
允许一个单独的实体跨过多个不同的域而不耦合它们。
事件队列
对消息或事件的发送与受理进行时间上的解耦。
服务定位器
提供一个全局的访问服务的指针,并且使用者不会和具体实现类耦合。
优化型模型
这里列举一些经常用来优化加速游戏的几个中级模式。
- 数据局部性介绍了现代计算机的存储层次以及如何利用它的优势。
- 脏标记模型帮助避免不必要的计算。
- 对象池避免不必要的内存分配。
- 空间分区会加速虚拟世界和其中元素的空间布局。
数据局部性
通过合理组织数据利用CPU的缓存机制来加快内存访问速度。
脏标记模式
将工作推迟到必要时进行以避免不必要的工作。
对象池
使用固定的对象池重用对象,取代单独地分配和释放对象,以此来达到提升性能和优化内存使用的目的。
空间分区
将对象存储在根据位置组织的数据结构中来高效地定位它们。