A Data-Driven Game Object System

来源:互联网 发布:张峰 java精品课程 编辑:程序博客网 时间:2024/06/06 06:59

在Cocos2d-x分会场,Cocos2d技术专家秦春林发表了《A Data-Driven Game Object System》主题演讲,主要讲述了A Data-Driven Game Object System。

 

Cocos2d技术专家 秦春林

以下是文字实录:

 

大家听了这么长时间,比较辛苦了,我希望大家轻松点,也能学点东西,我30分钟尽快讲完,我相信这堂课大家有很多东西去学习的,估计你们在其他课程里面也很难听到这样课程。后面这堂课也是比较有意思,也是Cocos2d-X在推的东西。


我这堂题目,我不知道大家有没有觉得这堂课是在讲数据运营的。数据驱动这个东西,其实在2002年的时候,在大会上有人提出这样一个概念,在游戏开发中遇到一些问题,自己设置这样一套模式。我们今天讲议题内容,前端架构,我们讲游戏对象的设计,我们游戏开发最多的办法,我们怎么样去设置这些对象。我们有没有更好的方式。


今天其实这个内容,它不是跟引擎相关的,这是一套架构思想,用Flash也可以,只是一套框架,把这套框架用在这种引擎上面去。前面大家讲的都是Cocos2d版本,我讲的是跟Cocos2d-X3.0版本。


日常我们在开会的时候我们会怎么做,我们就是一般用,就是最传统的,我们所有设计软件面向对象都可以搞定,你现在做软件,现在做游戏,设计个对象有什么行为,有什么数据,只要会开发软件,任何软件开发上都没有问题。这是对传统的,我相信可能大部分团队都是这么在用,包括前面PPT里面有一个什么足球的,下面有一个球员有自己的封装,都是这样一种方式。


有的自己会封装,采用MVC的方式,但是其实说实话我觉得MVC还是不太适合用。
   
Game Object


1、每个游戏都由某种形式管理Game object的机制。
2、负责创建和管理Game object。
3、管理所有Game object的ID,Game objectFind
4、Game object之间的消息传递。
5、通常引擎会提供一部分功能。
6、体现架构(游戏对象方面)的地方。


如何设计游戏对象


一般来说就是这样,设计拿过来以后我们一看有这样一种角色,一种单位,很自然形成这样一幅图,去弄,去设计,去画一些图。但是这很好,其实做所有软件都是这么来做,游戏里面它的问题就是,它会频繁改需求,就说因为就是我们有些上线之后它都在改,因为它的东西都是会不断调试,这时候面临更改,在游戏里面是很常见的。我们新增一个单位,它可能要继承一两个,之前两个内容某些功能,但是它不全,这个时候我们怎么办,是从这两个继承,还是说我们把这代码复制一部分出来,形成一个新的类,还是要把代码往上移,这时候有这样一些选择。这都是继承了一些问题,它的问题只要需求一改我们马上就会改。


我体会最深当设计拿过来之后我们脑袋想好了这些类怎么样,想好了,有一天改了就会导致我们这边改很多。因为在我们开发者脑子里它就要有一种这个对象一定要做这个事情,我们把它分得很清楚,我们做得很清楚。如果很混乱的状态,我们感觉不舒服,比如耦合很多。这时候你一定要把你的计算关系重新调整一下。更符合这种需求对象系统。所有这些都会导致我们重构。


我们所做的所有这些游戏对象的设计,其实就是把数据库里面每一个表转换成一个对象,其实我们是在干这么一件事情,我们所有事情用hard coding database,我们需要使用,形成这样一些封装,这是我们做的事情,其实跟这个数据是完全无论的。我们关注结构而不是行为,关注这个对象应该形成什么样的行为。


这是我们现在今天讲的架构一个出发点,并不是我们用组合模式,组合模式是我们出发点。我们将这些逻辑全部拆分出来,动画,AI,我们把它抽出来,每个按一个单位行为,最小单位,不再包括其他行为。抽出来就导致了我们游戏对象最后变成了一个ID,它可以没有任何数字。所以这是使用ID很大很重要的观念,我们让它有碰撞,我们让它有AI,通过这样一种思路来做,我们就是一个扁平的结构,而不是竖形的结构,这样改动就应对比较频繁需求的改变。每个Entity仅仅是一个ID。


Conference是Entity的数据,不是我们脑袋中想象数据库中数据,是一种行为数据,比如说目表示一种行为,目并不存在,这是一种行为,我们把它抽象成Conference,Conference还不包括任何的逻辑。这些Conference它全部是原子行为的数据,它不能再拆分了,比如说我们的碰撞里面,不能包括其他的,如果包括其他的还拆分,不会依赖其他的组建。


这样我们能够去定义一个游戏对象了,只要把部分东西组合起来就行。这边是表示我们游戏当中定的一些对象,比如有子弹、有英雄,可能还有关卡控制一些,横着我们表示是一些组建,比如说目、枪之类的,组合到某一个对象上去,通过这样一种方式来组合形成一个游戏对象,这样一个图应该比较直观。


这里面会定义一个管理器,它负责说,这个Entity它有哪些组建,我们会查询,这样一个对应关系。所以到现在为止,定义有这个Conference,我们会取得所有Entity实例,并且取到所有它的Conference,我们就把游戏对象定义好了。接下来我们这些逻辑在哪里呢,现在全是数据没有逻辑。

那我们的逻辑在哪里,就是第二个东西,就是System,所以System跟Conference是一样的,System是某一个行为的逻辑。


1、System包括一种行为的逻辑。
2、System只有一个实例、不能包含数据。
3、System遍例所有的Entity,找到满足条件的Entity,执行游戏逻辑。
4、COllisionSystem、AISystem、MOVESystem等。
     
ECS怎么工作的?


System是个行为锁,具有某种功能,我们这里就是个碰撞锁,它是锁了,只要谁有钥匙能打开它,它就去执行这个逻辑,执行碰撞。那System就定为一把锁。找到所有碰撞组建的实体,还需要Rendre。
          
System之间怎样传递消息


因为System就是一个单粒,我们在传统当中,我们有一个Player 我们会保持枪的引用,这样就是两个对象之间就耦合了,如果我们通过消息来传递就更好,System之间需要用到消息分发引擎。分发方式在目前Cocos2d-X版本里面,他们也吐槽了,现在消息分化方式。这是Cocos2d-X3.0方式,包括你自定义的,Cocos2d-X3.0里面比较好的东西。


所以这个我们的原则就是总是使用事件,你这个行为跟另外行为之间交互,你就要定义为一个事件,不会说我这个去直接引用这样一个东西,比如说我们要发子弹,我们就定义枪的事件,我只要发出去就可以了,我这个Colliston就做完了。我这个英雄死了,也不是说死了调另外一个去,只要涉及到两个逻辑之间需要交互的地方,我们总是使用事件,这是ESC里面最大的。


它不能使用this指针。所以它这个里面this就没有意义了。我们在传递事件的时候,一定要把我们的Colliston它是不知道处理谁的,它是一个单粒的。这样我们就能够满足在Colliston之间,System之间形成通信交互。最后这个代码是Cocos2d-X3.0代码写的,我写了完整Cocos2d-X系统项目比较简单,待会儿我把地址给大家,包括我这边讲到的,待会儿我归演示一下。


还有一个就是回调,这个动画执行完要回调,因为它是只有一个实例,它的this指针没有回调。是哪个结点执行,这个方法它没有保存这样一个定量的话,回到说把对象再返回来,这个时候我们需要注意,这个回调可能是我们自己定义的,你可能需要保存一下这个对象传回来。这是Cocos2d-X3.0比较大的好处,现在Cocos2d-X完全是C++的,Cocos2d-X3.0你会发现,所有东西你都可以写Lamda格式。


下面我们看一下DEMO,这个游戏,中间有个酒店,周边都是房子,你用房子放上去就可以保护这个酒店,外面有一些怪物。


代码网上有,待会儿你们自己去看,首先来将,我们先运行一下。我只演示一个就行了,大家理解一个就好了。这样一个例子,我们中间有个船,我们一点的话会产生一个单位,会发现这个怪物是不动的,啥也没有,不包括任何逻辑。我改一行代码,比如说我们改行代码,这里面,我放到这里面来,这里面我就干一件事情,我们只加上这么一个组件它就可以走了,我们再把后面两个加上,它就可以发射子弹了。你看它就可以发射子弹。所以说你看我们后面的代码,其实只是加了两个Colliston。定义我们第三种单位,这个单位是保护这个酒店,待在那里发现怪物就要打。


我不用设计任何对象,我不用去管任何对象的结构,如果大家回去下载代码,大家会看到左边,我这边没有任何类跟结构相关的。我只要去想一个最小的行为就行了。我下面所有定义跟行为相关的,而且这里面每个行为代码量非常少。


最后看一下职责,我这里面大概提一下。

1、ECS不依赖于任何引擎,是独立的系统。
2、System更关注行为,不应该摄入太多元素绘制等相关的工作。
3、UI元素的创建,层级结构等管理属于引擎。
4、用户输入Mouse,touch等管理属于引擎。
5、物理相关属于引擎。
6、自定义控件等属于引擎。
     
可视化设计


这是很成熟的方式,现在Unity完全是基于这个方式设计引擎的,现在目前来讲之前没有这样的方式,其实它早期就比较简单,快速做游戏,所以它没有整体这样去设计,但是我们去看Unity的话,它整个都是由组件方设计的。


你加上一个碰撞你就可以碰撞了,所以Unity里面以组件来设计的,这个就涉及到我们这堂课的主题,就是数据驱动,我们通过数据配置就可以定义一个游戏对象,在编辑器里面,或者在其他器里面执行我们游戏逻辑,所以做关卡什么都是非常方便的。这个时候我们还可以做很复杂的这种UI的创建。而每个层级每个结点里面又有行为,这个时候你是不好去弄的,如果我们有组件,有再多子元素,这个控件,为什么它很容易。


只要使用这个方式,它就可以编辑的时候你去运行就根据这些把它弄出来,执行你的脚本就可以了。这就是可视化设计一个原理,一种方式,可视化设计,刚刚前面讲红孩儿设计,有一种方式,针对每一种类型游戏对象,去改属性,这是最传统一种,其实基于组件的方式,这个组件它是做什么的,脚本不光能显示出来,还能执行逻辑,是一种比较好的可视化逻辑。


估计以后的话Colliston在这上面组件支持的,这样才能做到真正很强大的可视化逻辑,可能你也可以做,你会定义很复杂,如果这个类型,你会很复杂,所以我们做可视化也可以利用这样的方式去做。


我们可以通过一个数据定义对象及行为。他把所有行为转化为数据,你只要在外面定义说有这个数据,所以说通过这种方式,就做到了数据驱动。
 

我们总结一下:


ECS的好处:
1、应对需求变更。
2、关注行为而不是结构。
3、支持可视化设计。
4、低耦合。
5、行为之间独立。
6、数据驱动。
7、逻辑分离。
8、游戏开发更简单、更快乐。

    

不足:

1、System每一帧查询Entity列表,可能上千。
2、std Map查找的复杂度与Size成对数。
3、按模块使用多个EntityManager实例。
4、System作为组件附加到Entity(Unity)的方式。
5、Cocos2d-X2.1.2以后的版本CCNode支持组件。


我还是讲原始的,大家去使用的时候,把System组件的方式放到Colliston里面去,后面我也会更新一个,或者再开一个分支,如果没有这个基本原理,也不会演变到Unity。


全新的Cocos2d-X3.0


1、EventDispatcher
2、集成、更简单的物理引擎。
3、EntitySystem。
4、与Sprite kit兼容、粒子、拼图。
5、全新的渲染机制。
6、2.5D支持。
7、多窗口。
8、C++Style STL lamda
9、Gui
10、增强的Label


这里面跟大家说一下,我现在正在写一本关于Colliston的书,里面基本覆盖Cocos2d-X3.0,在发布不久,希望大家感兴趣的到时候关注一下。

原创粉丝点击