抱歉,你查看的文章不存在

组件-实体-系统 (ECS \CES)游戏编程模型

一般来说,我们实现游戏实体都是采用面向对象的方法进行编程。每一个实体都是一个对象,并且需要一个基于类的实例化系统,允许实体通过多态 来扩展。但是,这样的方法,往往导致系统中出现大量的类,造成类爆炸的情况出现。随着新的实体出现,我们发现很难在类继承图中添加新的实体,特别是当这个 实体需要很多不同类型的功能的时候。你可以看下下面的一个简单的类图继承。一个静态的敌人,并不能够很好的继承出来。

为了解决这样的问题,游戏开发人员想出了通过组合而不是继承的方法来进行实体的构建。一个实体,就是一群组件的聚合,通过这样的方式,它具有以下面向对象方法所不具有的好处:

1.容易添加新的复杂的实体类型

2.容易定义新的实体数据

3.更加的高效率

下面是如何实现实体的一种方式。注意,这里的组件都是纯粹的数据,没有任何的方法,在下面会详细解释为什么这么做。

一 个组件可以使用C中的结构体来进行设计。它没有方法,只是用来存储一些数据,并不在它之上进行动作。一个经典的实现方式是,每一个不同的组件都继承至一个 抽象的Componet类,通过这样的方法我们能够在运行时动态的添加组件,识别组件。每一个组件都描述了实体的某个属性特征。当他们单独存在的时候,实 际上是没有任何意义的,但是当多个组件通过系统的方式组织在一起,就能够发挥强大的力量。我们可以使用空的组件来对实体进行标记,从而能够在运行时动态的 识别它。

例子

1Position(x,y)
2Velocity(x,y)
3Physics(body)
4Sprite(images, animations)
5Heath(value)
6Character(name, level)
7Player(empty)

一个实体指的是存在于你的游戏世界中的物体。实体在代码上就是一个组件的列表。由于实体的结构实在是太简单了,所以很多实现都没有专门的设计一个实体的数据结构。 相反的,一个实体就是一个ID,所有组成这个实体的组件将会被这个ID给标记,从而明确的知道哪些组件是属于哪个实体的。如果你想的话,你可以在运行时, 动态的将组件从实体中移除或者增加一个或多个你感兴趣的组件。比如说,如果玩家发出了一个冰系魔法,将敌人冻住,你只要简单的将它的速度组件移除,那么敌 人就静止住了。

例子

1Rock(Position, Sprite)
2Crate(Position,Sprite,Health)
3Sign(Position,Sprite,Text)
4Ball(Position,Velocity,Physics,Sprite)
5Enemy(Position,Velocity,Sprite,Character,Input,AI)
6Player(Position,Velocity,Sprite,Character,Input,Player)

由于 系统只会对相关联的组件进行操作,所以组件就定义了一个实体所应该具有的行为。比如说,如果一个实体有一个Position组件,但是没有 Velocity组件,那么我们就知道,这个物体是静止不动的,系统就不会对这个实体的Position组件进行操作了。当我们对这个实体增加了一个 Velocity组件的时候,系统就会使用Velocity组件来对物体进行移动。这样的行为可以使用被标记的组件来进行,被标记的组件能够重复的使用在 不同的上下文中。对一个实体,增加一个空的Player组件,将会为这个实体打上了Player的标签,那么PlayerControl系统,就会寻找带 有这个标签的所有组件,然后使用Input中的数据,进行操作。

例子

1Movememt(Position, Velocity) - 将速度增加到位置上去
2Gravity (Velocity) - 使用重力来对速度进行加速
3Render(Position, Sprite) - 绘制精灵
4PlayerControl(Input, Player) - 更具Input中的数据控制Player
5BotControl(Input, AI) - 更具AI代理和输入的数据控制

使用了CES系统之后,我们就可以避免使用大量的类了。实体就是你游戏中存在的物体,它隐式的使用一系列的组件进行定义,这些组件都是纯粹的数据,只有系统才能够操作他们。

我希望我已经成功的向您解释了什么是CES系统,并且你有欲望在自己接下来的项目中试试这个系统的效果。如果你有任何关于本片文章的疑问,很感谢你在后面留下你的问题。

github:https://github.com/Golangltd/ecs

Google资深工程师深度讲解 Go语言基础到实战系列 (www.Golang.Ltd论坛提供下载链接)

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2018-06-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

Golang语言社区

1783 篇文章342 人订阅

相关文章

来自专栏点滴积累

geotrellis使用(十)缓冲区分析以及多种类型要素栅格化

目录 前言 缓冲区分析 多种类型要素栅格化 总结 参考链接 一、前言        上两篇文章介绍了如何使用Geotrellis进行矢量数据栅格化以及栅格渲染,...

3648
来自专栏Web 开发

知呼前端工程师面试题目

第三题的答案(我的答案有点问题,等弄好了再上传 要想完美,先出主体,通过负margin+双容器)

890
来自专栏Golang语言社区

【go语言】Goroutines 并发模式(一)

摘要 这一篇主要是对GO语言中的并发编程模式做一个粗略的归纳总结,文中示例参考自golang conference中的一些演讲和博客,go涉及到的Go语言的语法...

3496
来自专栏CSDN技术头条

Java 平台反应式编程(Reactive Programming)入门

反应式编程(Reactive Programming)对有些人来说可能相对陌生一点。反应式编程是一套完整的编程体系,既有其指导思想,又有相应的框架和库的支持,并...

1.8K6
来自专栏王大锤

iOS中的预编译指令的初步探究

4198
来自专栏自动化测试实战

Appium 定位方法例子(4)

3534
来自专栏申龙斌的程序人生

解密310 BTC(2)

价值1400万的比特币猜谜游戏刚火了几天,大奖就被一位高手全部取走,310 BTC的破解过程现在还没有公开,但已经有黑客公布了第二关的解法视频,过程相当复杂,我...

2021
来自专栏java一日一条

关于 Unicode 每个程序员应该知道的 5 件事

上周末,曝出了山寨WhatsApp Android应用程序的新闻,看似由相同的开发者提供作为了官方应用程序。欺诈分子通过在开发者名字中包含unicode非输出空...

912
来自专栏编舟记

Clojure集合管道函数练习

TDD讨论组里的申导最近在B站直播了Martin Fowler的经典文章Refactoring with Loops and Collection Pipeli...

1462
来自专栏守候书阁

大道至简--API设计的美学

对于前端开发而言,肯定会和API打交道,大家也都会想过怎么设计自己的API。优秀的 API 之于代码,就如良好内涵对于每个人。好的 API 不但利于使用者理解,...

1683

扫码关注云+社区

领取腾讯云代金券