Game Objects:

Dynamic game objects:角色,载具…

Static game objects:房子,岩石….

Environment:天空,植被,地势….

Other object:空气墙,检测区域….

对于一个game object,它既存在Attributes(属性),也拥有Behaviours(行为),因此定义一个类来描述它是最好的方法;与此同时,在这个game object的基础上,还可以加上更多的属性与行为,使其成为另一个全新的对象,这里自然而然地会想到用继承来定义另一个新物体。

但是很多时候,这两个物体之间并不是严格的父类与子类的关系(e.g.水路两栖车到底派生自车类还是船类?),所以,现代游戏引擎通常会使用Component Base(组件化)的方法来解决这一问题:将单个game object的许多不同部件拆分出来,作为单独的函数,在ComponentBase这个基类中定义基础的属性接口

总结:1.在游戏世界中,所有物体都被抽象为Game Object

2.所有的Game Objects又由许多的Component组成

如何构建动态的世界:

通过Tick()实现

游戏画面实际上是由大量连续帧组成的,以30fps为例,引擎每1/30秒就会调用一次Tick()函数,对动画,物理等等进行更新,但这里的Tick()并不是逐对象实现,而是逐组件实现的(e.g.先完成动画系统的更新,再去进行相机系统的更新)

Why:简单来说,就是现代计算机流水线的批处理效率比逐个处理单物体的效率要高

如何创建交互:

通过事件进行

当对象发生某个行为时,周围的其他对象可能需要对这一行为作出反应,在早期的游戏引擎中,这一部分通常是Hard Code,即在类中定义所有对象对于这一行为的反应。

但随着游戏对象的复杂化,硬编码的效率太低,有时甚至无法运行,于是出现了另一种方法:事件;对于每个对象,它并不需要知道周围其他对象应当作出何种反应,他只需要告诉对应的game object发生了什么事件,之后交由其他对象自行调用对应的方法并产生影响

如何管理Game Objects:

既然已经知道发生了某个事件,那应该如何寻找到受影响的物体?

在小型游戏中,可以通过将地图划分为一个一个的小格子,以此来判断哪些区域(格子)内的物体会受到影响;

但是游戏内的资源分布往往是不均匀的,如果平均划分的话会产生性能浪费,所以应当使用更加高效的场景管理策略,比如:BVH,八叉树等等

更加复杂的情况:

在很多情况下,消息的发送并不是单向的,而是会在多个系统之间双向进行,因此消息发送的顺序尤为重要;为了解决顺序的问题,引擎通常会将所有消息先收集起来,之后再按照一定的顺序进行发送(e.g.相当于邮局,对象将所有的信件都先寄邮局,之后再由邮局按照顺序统一发出)

原文:如何构建游戏世界