【Games104】 如果构建游戏世界

一、Game Object

1、什么是Game Object

游戏中的万物皆为游戏对象(Game Object,GO),包括静态(房子)、动态(人)、环境(天空、树)、其他GO(检测体、空气墙)等。构建一个游戏世界,就是要管理好这些GO。

2、GO的属性

【Games104】 如果构建游戏世界_第1张图片

一个GO可以定义为一个类,其属性(Property)和行为(Behavior)对应了类中的成员变量和成员函数。这个很easy。进一步,我们可以建立父类,由父类派生不同类型的子类,继承关系便是面向对象编程的基础。

【Games104】 如果构建游戏世界_第2张图片 然而游戏世界的定义一个GO并不是单纯一个继承的关系,一个子类可能同时拥有多个父类的特点,如何实现这个GO的定义,便成了关键。

一个最经典的解决方法便是:组件化。把一个GO的行为拆分成多个组件。如下图,一个无人机的对象,我们可以拆卸成为多个组件,当这些组件组合在一起,便是我们需要的GO,同样的我们也可以通过增删改组件来建立相似但是不同的GO。 

【Games104】 如果构建游戏世界_第3张图片

二、 Object-based Tick vs. Component-based Tick

当前一Tick内的执行方式主要分为两种,一种是基于对象,即在一Tick内一个GO的所有组件都执行完再执行下一个GO的组件,这种方式更简便而且更易于DEBUG;另一种是基于组件的,即将不同GO的相同组件并行执行,加快了效率同时减少了缓存的丢失,当今的游戏引擎的执行策略多以第二种为主。

【Games104】 如果构建游戏世界_第4张图片

 三、Event

在过去的游戏设计中,GO与GO之间的交互是采用HardCode的方式进行的,例如一个炮弹爆炸,在爆炸的函数中就要求遍历出所有可能与“爆炸”这个行为相关联的对象,再去对那个对象进行修改。而如今GO越来越复杂的情况下,这种编写方式不再work,从而出现了一种Event的机制来解决这个问题。

Event机制,是一种消息传递的机制,一个GO的行为会产生一个事件,将这个事件传递给其他GO,其他GO再去处理。以刚才举的例子来说,炮弹爆炸产生一个爆炸事件,这个事件传递给周围对象,周围的对象在下一个Tick接收到这个event,同时进行对应的行为。

 【Games104】 如果构建游戏世界_第5张图片

四、管理GO

一个事件产生就需要传递,传递给哪些GO变成了问题,所以我们需要去管理所有的GO。 最简单的方式就是不管理,当一个事件产生就发送给所有的GO,做一个小游戏的时候这样是没用问题的,但是当GO越来越多,这样明显是灾难性的。

【Games104】 如果构建游戏世界_第6张图片那么最简单的管理方法就是将区域划分成层级结构,上图举了一个四叉树的例子,将区域按层级划分成四块,按层级查询便可以快速得到想要的结果。同时,这种层级结构也分为不同的流派,比如八叉树、BSP(二进制空间划分)以及最常见的BVH等。

五、其他复杂情况

【Games104】 如果构建游戏世界_第7张图片

一个游戏场景中的GO都是在行动的,会有大量event发送和接收,如果是单线程运行,什么时候发送什么时候接收是没用问题的。但是现在的游戏是多线程并行执行的就可能产生一些时序问题。例如辆车相遇,A发送信号让B停,B发送信号让A停,由于是并行的,两个event并不是同时发出的,到底是A先停还是B先停还是同时停整个时序是混乱的,如果一个场景中大量存在这种时序混乱,则大大降低了整体的运行效率。所以提出了一种“邮局”作为中介的方法,所有的Event要求先传递给“邮局”,邮局在下一个Tick同时发送给对应的GO,这样解决当前的时序混乱的问题。

你可能感兴趣的:(games104,游戏)