转载自:http://blog.csdn.net/i_dovelemon/article/details/25798677

理解 组件-实体-系统 (ECS \CES)游戏编程模型 - 博客频道

 

原文出处:点击打开链接

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

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

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

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

3.更加的高效率

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


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

例子

  • Position(x,y)
  • Velocity(x,y)
  • Physics(body)
  • Sprite(images, animations)
  • Heath(value)
  • Character(name, level)
  • Player(empty)

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

例子

  • Rock(Position, Sprite)
  • Crate(Position,Sprite,Health)
  • Sign(Position,Sprite,Text)
  • Ball(Position,Velocity,Physics,Sprite)
  • Enemy(Position,Velocity,Sprite,Character,Input,AI)
  • Player(Position,Velocity,Sprite,Character,Input,Player)


意,我在上面没有提到任何和游戏逻辑相关的话题。游戏逻辑是系统需要进行的工作。一个系统就是对所有相关联的组件记性操作,比如说,同一个实体的组件。举
个例子,人物的移动系统可能会对位置(Position),速度(Velocity),碰撞(Collider),和输入(Input)进行操作。每一个
系统,都会在每一帧中按照逻辑上的顺序进行更新。如果要让一个角色跳起来,我们只要检测下Input中的keyJump按键是否被按下,如果是,那么系统
就会查看下载Collider中是否有一个接触了地面,如果是,就将这个实体的Velocity的y速度设置一下,让这个物体跳起来。

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

例子

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

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

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

 

ECS 游戏架构 理解的更多相关文章

  1. ECS 游戏架构 应用

    转载自:http://blog.csdn.net/i_dovelemon/article/details/30250049 如何在cocos2d-x中使用ECS(实体-组件-系统)架构方法开发一个游戏 ...

  2. ECS 游戏架构 实现

    转载自:http://blog.csdn.net/i_dovelemon/article/details/27230719 实现 组件-实体-系统 - 博客频道   这篇文章是在我前面文章,理解组件- ...

  3. 解构C#游戏框架uFrame兼谈游戏架构设计

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

  4. TAF /tars必修课(一):整体架构理解

    来自零点智能社区 一.前言 TAF,一个后台逻辑层的高性能RPC框架,目前支持C++,Java, node 三种语言, 往后可能会考虑提供更多主流语言的支持如 go等,自定义协议JCE,同时也支持HT ...

  5. 沉淀再出发:Spring的架构理解

    沉淀再出发:Spring的架构理解 一.前言 在Spring之前使用的EJB框架太庞大和重量级了,开发成本很高,由此spring应运而生.关于Spring,学过java的人基本上都会慢慢接触到,并且在 ...

  6. 【转载】U3D 游戏引擎之游戏架构脚本该如何来写

    原文:http://tech.ddvip.com/2013-02/1359996528190113.html Unity3D 游戏引擎之游戏架构脚本该如何来写   2013-02-05 00:48:4 ...

  7. Unity《ATD》塔防RPG类3D游戏架构设计(二)

    目录 <ATD> 游戏模型 <ATD> 游戏逻辑 <ATD> UI/HUD/特效/音乐 结语 前篇:Unity<ATD>塔防RPG类3D游戏架构设计(一 ...

  8. Unity《ATD》塔防RPG类3D游戏架构设计(一)

    目录 <ATD> 游戏简介 <ATD> 整体结构 <ATD> 游戏机制 Buff机制 Skill机制(技能机制) 仇恨机制 <ATD> 游戏模型 策划案 ...

  9. ARM CORTEX-M3 内核架构理解归纳

    ARM CORTEX-M3 内核架构理解归纳 来源:网络 个人觉得对CM3架构归纳的非常不错,因此转载 基于<ARM-CORTEX M3 权威指南>做学习总结: 在我看来,Cotex-M3 ...

随机推荐

  1. golang的interface到其他类型的数据转换

    以string为例 package main import "fmt" func main() { var a interface{} var b string a = " ...

  2. Tomcat原理的一点看法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 首先,运行tomcat之前,先写一个html页面, 再写一个serlvet程序 配置文件如下: 那么程序是怎样运行的呢? 浏览器发起请求到 --& ...

  3. 干货:这也许是最全面透彻的一篇RabbitMQ指南!

    本文大纲: RabbitMQ 历史 RabbitMQ 应用场景 RabbitMQ 系统架构 RabbitMQ 基本概念 RabbitMQ 细节阐明 历史-从开始到现在 RabbitMQ是一个Erlan ...

  4. CSS各浏览器HACK

    /*firefox*/@-moz-document url-prefix(){.mainNews div.l ul{padding-bottom:12px}} /*ie6*/{_padding:2px ...

  5. offset()和position()

    网上百度都有的说明是 offset():获取匹配元素在当前视口的相对偏移. position():获取匹配元素相对父元素的偏移. 如果单纯写这两句话,这个博客毫无意义 这里我写下他俩的使用情况,希望对 ...

  6. 通过socket实现处理多个连接,send和resv都是有数量限制的

    我们现在先来实现,跟一个人来来回回不停的讲电话. 客户端,通过循环来输入多次命令: client.recv(1024)每次只接收1K的内容 服务端来改成多次接收:如果你写成如下的代码: 那么造成的结果 ...

  7. MapReduce项目中的一个JVM错误问题分析和解决

    最近一周都在查项目的各种问题,由于对原有的一个MapReduce分析数据的项目进行重构,减少了运行时的使用资源,但是重构完成后,在Reduce端总是不定时地抛出JVM的相关错误,非常随机,没有发现有什 ...

  8. Cloudstack 安装记录

    一.条件要求 1.硬件支持虚拟化,并在BIOS中开启(Inter-VT设为 Enable). 2.Centos 6.5 x86_64 3.环境中的每台主机均为静态IP地址. 4.cloudstack安 ...

  9. Julia - 复数

    全局变量 im 即复数 i ,为复数的虚数单位,表示 -1 的正平方根 Julia 允许数值作为代数系数,这也适用于复数 julia> 1 + 2im 1 + 2im 复数的运算 julia&g ...

  10. Jmeter如何监控服务器性能

    1.jmeter只需要安装一些插件 ,就可以像loadrunner一样监控服务器CPU.内存等性能参数 1.下载需要的jmeter插件      如图上面两个是jmeter插件,可以再下面的链接中下载 ...