每当我尝试用任何面向对象的语言编写游戏时,我总是要面对的第一个问题(在考虑编写哪种游戏之后)是如何设计引擎。即使我正在使用现有的库或框架(例如SDL),我仍然发现自己必须为每个游戏做出某些决定,例如是否使用状态机来管理菜单,用于资源加载的类类型等。
什么是好的设计,将如何实施?需要进行哪些权衡以及它们的利弊?
每当我尝试用任何面向对象的语言编写游戏时,我总是要面对的第一个问题(在考虑编写哪种游戏之后)是如何设计引擎。即使我正在使用现有的库或框架(例如SDL),我仍然发现自己必须为每个游戏做出某些决定,例如是否使用状态机来管理菜单,用于资源加载的类类型等。
什么是好的设计,将如何实施?需要进行哪些权衡以及它们的利弊?
Answers:
我怀疑有人会说:“您必须使用模式X来执行该操作,该操作以及该操作与该操作”。
但是,有一些有用的资源:
Enginuity-Gamedev.net上的一系列引擎构建文章。
游戏编码完成 -我拥有这本书,它很好地涵盖了游戏编程的各个方面。在本书中也确实内置了引擎。
游戏引擎架构 -这是关于引擎设计的另一本好书。
C4引擎布局 -摘自我的评论,但这显示了将引擎各部分装配在一起的高级方法。
这些对于您所需的内容可能有点过多,但是您对某些内容了解得不多,我相信您会从中得到一个好的计划。
编辑:我忘了自新站点以来,已将Gamedev文章存档:)
举例来说,这就是我当前的类似roguelike项目的结构(使用Java)。它使用2D图形引擎,因此很多渲染代码已经为我解决了。欢迎批评。
class Game
此类设置了状态机来管理游戏的当前状态。(在菜单中与开始新游戏与在播放保存的游戏中)
interface State
每个State类包含两个循环:一个用于更新逻辑的循环和一个用于呈现的循环。它们还包含用于调用Game
类并请求更改为其他状态的代码。
class ResourceManager
由Game
类初始化的单例,该单例加载所有需要的资源并允许对其进行访问。我不喜欢这种设计,因为它使例如在不同级别上加载/卸载资源变得困难。如果我要从头开始,我可能会对此进行不同的设计。
class Map
一张地图包含一组瓷砖以及该地图上所有生物和物品的列表。这是一个非常基础的课程。
class Creature
生物包含有关自身的信息,包括运动计算(要求他们知道他们所处的地图,并能够对其进行查询以找出障碍物)。我要努力决定是否要这样做,还是让某种管理者班上的所有生物都来照顾它。
interface AITask
生物可以有一个AITasks列表,该AITasks列表在每次运行该生物的逻辑循环时都会执行。AITask具有其自己的逻辑循环,用于向生物发出命令,以及终止条件,用于确定任务是否成功完成。
interface UIElement
我为此引擎实现了自己的UI。每个UIElement都有一个渲染循环和一个逻辑循环。它们还具有用于处理键盘/鼠标输入的循环。所有元素可以具有许多子元素,这些子元素在其父元素之后呈现,并接管键盘/鼠标输入。例如,这使您可以使用带有子菜单的菜单。
首先要指出的是,这个问题没有一个“好的”答案。
正确答案最接近的是:很大程度上取决于游戏的类型,目标平台,约束(时间)等。
就是说那里有一些非常好的文章,这些文章将向您展示其他人如何尝试解决此问题(因为我过去曾尝试查找有关此问题的信息)。
正如共产主义鸭子所说的关于游戏开发者的工程学文章帮助我理解了游戏体系结构的某些部分。
我当前的设计是Quake3 / Doom3和.NET类库的一点混合:)
我有两个库(静态或动态取决于你想如何构建/交付)的Framework
和Library
。
该库包含所有帮助类,可以帮助您制作游戏软件,但不仅限于此类产品。即,它具有链表的实现,该链表已针对游戏代码进行了优化,但可由需要链表服务的任何人使用。
如果您想将其称为“引擎”,那么框架就是胆量。其中很多都遵循Quake3的设计理念(只是以更面向对象的方式)。它包含CLI,时序管理,特定于OS的代码以及最终的网络层等。
然后将这两个链接与正在生成的实际应用程序联系起来。的Game
,如果你喜欢,它包含了游戏的特定代码。与Quake3加载DLL的方式大致相同,具体取决于播放的是“ mod”。
为了让您对结构有所了解,这里是每个库的文件夹和内容的快速细分:
HTH!应该给你一些指示...
要考虑的事情
好的设计
数据是编程的关键。如果您希望数据良好,通常会从中产生算法(如果您不计算某些数值算法,例如计算行列式)。