实体组件系统_实体组件系统介绍

本文是对实体组件系统(Entity Component System)的介绍,来源于Dean J. K. James在Medium上的文章,探讨了这种软件架构模式的基本原理和应用。
摘要由CSDN通过智能技术生成

实体组件系统

什么是实体组件系统?(What is Entity Component System?)

Entity Component System is a software pattern commonly employed in game development.

实体组件系统是游戏开发中常用的一种软件模式。

It is designed to take full advantage of a computer’s hardware to maximize performance, whilst also providing the programmer with a structured, modular environment.

它旨在充分利用计算机硬件的优势来最大化性能,同时还为程序员提供结构化的模块化环境。

Image for post
The three parts to ECS
ECS的三个部分

The pattern comprises three parts: entities, components, and systems.

该模式包括三个部分:实体,组件和系统。

一个例子 (An Example)

To better explain the concepts involved in the ECS pattern, consider a 2D platformer with the following objects:

为了更好地解释ECS模式中涉及的概念,请考虑具有以下对象的2D平台程序:

  • A player controlled by a mouse and keyboard.

    由鼠标和键盘控制的播放器。
  • A static tree.

    一棵静态树。
  • Two zombies controlled by AI.

    由AI控制的两个僵尸。

在OOP中会是什么样? (What Would this Look Like in OOP?)

In object oriented programming, data and functionality are kept tightly encapsulated within classes, promoting inheritance like in the following diagram:

在面向对象的编程中,数据和功能紧密地封装在类中,从而促进了继承,如下图所示:

Image for post
Inheritance diagram for some classes
某些类的继承图

Here, a parent GameObject class contains all common data and functionality. Different classes would inherit and override this.

在此,父GameObject类包含所有通用数据和功能。 不同的类将继承并覆盖它。

ECS中的情况如何? (What Would this Look Like in ECS?)

ECS doesn’t keep data and functionality coupled together in classes, nor does it use inheritance. Instead, it seperates them like in the diagram below:

ECS不会将数据和功能保持在类中耦合在一起,也不会使用继承。 相反,它将它们分开,如下图所示:

Image for post
Three parts to ECS
ECS的三个部分

All data is seperated into small, specialised components, and all functionality and logic is kept in specialised systems. The entity is an identifier that binds everything together.

所有数据都分离为小型的专用组件,所有功能和逻辑均保存在专用系统中。 实体是将所有内容绑定在一起的标识符。

Following is a more detailed description of the three concepts of ECS.

以下是对ECS的三个概念的更详细描述。

实体 (Entity)

An entity is an individual object in the world. The following diagram shows the four entities in our game:

实体是世界上的单个对象。 下图显示了我们游戏中的四个实体:

Image for post
The four entities in our game
游戏中的四个实体

In a program using ECS, each entity is represented by a unique integer id. The entity itself contains no data or functionality; it is just an integer.

在使用ECS的程序中,每个实体都由唯一的整数ID表示。 实体本身不包含任何数据或功能; 它只是一个整数。

组件 (Components)

All the data associated with an entity is seperated into small, generic, and reusable components.

与实体相关联的所有数据都被分离为小型,通用且可重用的组件

Below are eight example components:

以下是八个示例组件:

Image for post
Some example components
一些示例组件

Each component is specific, independent, and usually contains only primitive data types like integers or floats.

每个组件都是特定的,独立的,并且通常仅包含原始数据类型,例如整数或浮点数。

For example, the following code represents the Position component:

例如,以下代码表示位置组件:

1.   public struct Position
2. {
3. public float x;
4. public float y;
5. }

Components are lightweight data containers that define the attributes and state of an entity. They contain no functionality, just data.

组件是轻量级的数据容器,用于定义实体的属性和状态。 它们不包含任何功能,仅包含数据。

The following diagram shows the four entities in our game alongside the components attached to them.

下图显示了我们游戏中的四个实体以及与其相连的组件。

Image for post
Each entity and their components
每个实体及其组成部分

All four entities have a Position and Render component. Entity 0, 1, and 2 have a Physics component, but entity 3 does not. Entity 0 has a PlayeInput component and entity 1 and 2 have an AI component.

所有四个实体都具有“位置渲染”组件。 实体0、1和2具有Physics组件,但实体3没有。 实体0具有PlayeInput组件,而实体1和2具有AI组件。

Components on there own just store data. They do not contain any methods and do not have any functionality. How the variables in a component are interpreted is not the concern of the component.

那里的组件仅存储数据。 它们不包含任何方法,也不具有任何功能。 组件中不关心如何解释组件中的变量。

组件阵列 (Component Array)

As mentioned, entities are just integers that don’t need to be stored anywhere. Components, however, do need to be stored in memory and are usually stored in arrays like in the following diagram:

如前所述,实体只是整数,不需要存储在任何地方。 但是,组件确实需要存储在内存中,并且通常存储在数组中,如下图所示:

Image for post
Components array for Position and Render
位置和渲染的组件数组

Each component type will have its own one dimensional array with each instance of a component being stored contiguous to the next.

每种组件类型都有自己的一维数组,每个组件实例与下一个实例相邻存储。

The relationship between the entity id and the component array depends heavily on how the ECS is implemented. Often, the entity id maps either directly or indirectly to the index of the array that the entity’s component is located.

实体ID与组件数组之间的关系在很大程度上取决于ECS的实现方式。 通常,实体ID直接或间接映射到实体组件所在的数组的索引。

For example the Position component attached to entity 35 will be at index 35 in the Position components array.

例如,附加到实体35的Position组件将位于Position组件数组中的索引35处。

系统篇 (Systems)

Systems bring the game to life. They operate on the components attached to an entity to produce changes in the world.

系统使游戏栩栩如生。 它们在与实体相连的组件上进行操作以产生世界变化。

The following diagram shows four example systems:

下图显示了四个示例系统:

Image for post
Example systems
示例系统

Each system is updated once per frame. During this, a set of entities, which are selected according to some filter, are iterated, and their attached components are modified.

每个系统每帧更新一次。 在此期间,将迭代根据某些过滤器选择的一组实体,并修改其附加组件。

Take the GravitySystem for example. Its requirements are that an entity has an attached Position and Physics component. The following code demonstrates what the update loop could look like:

以重力系统为例。 它的要求是实体具有附加的“位置物理”组件。 以下代码演示了更新循环的外观:

1.   foreach (int e in GetEntities<Position, Physics>())
2. {
3. Physics phy = physics[e];
4. Position pos = position[e];
5.
6. phy.velocity_y -= 9.81f;
7. pos.y += phy.velocity_y;
8. }

(This code is for demonstration purposes and will not compile)

(此代码仅用于演示目的,不会编译)

  • Line 1 iterates over every entity that has the required Position and Physics components.

    第1行遍历具有所需“位置物理”组件的每个实体。

  • Line 3 and 4 grabs the instances of each component belonging to the current entity from the relevant component arrays.

    第3和第4行从相关组件数组中获取属于当前实体的每个组件的实例。
  • Line 6 and 7 modify the component instances.

    第6和7行修改了组件实例。

The GravitySystem will only work on entities that have the required components, which in our game, is entity 0, 1, and 2. Entity 3 does not have an attached Physics component and so is not used by the GravitySystem.

GravitySystem将仅在具有必需组件的实体上工作,在我们的游戏中,实体是实体0、1和2。实体3没有附加的Physics组件,因此GravitySystem不会使用

Like components, systems are specific. The GravitySystem applies gravity. A RenderSystem renders entities with a Position and Render component. A HealthRegenSystem regenerates the health of entities with a Health component.

像组件一样,系统也是特定的。 GravitySystem应用重力。 RenderSystem使用“位置渲染”组件渲染实体。 HealthRegenSystem使用“健康”组件重新生成实体的健康

结论 (Conclusion)

Hopefully, this article has successfully introduced the basic concepts of ECS.

希望本文成功介绍了ECS的基本概念。

Actually implementing an ECS can be a challenge. Fortunately, there are lots of resources online that can help with this. Below are some that I used.

实际实施ECS可能是一个挑战。 幸运的是,在线上有很多资源可以帮助您解决此问题。 以下是我使用过的一些内容。

翻译自: https://medium.com/@dean.j.k.james/introduction-to-entity-component-system-64c371f274bd

实体组件系统

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 概述<br>BOS(Basic Object System)的目的是提供一个纯粹的组件使用环境。在这个环境中,软件完全由组件构成而没有额外的代码,甚至不需要撰写main函数。这个环境不仅使得软件的结构更佳,更进一步使得软件开发的性质发生变化—开发人员不再为特定的程序付出封闭的辛劳,他们写下的每一行代码现在都属于某个组件,因而总有可能在将来被复用。<br><br>BOS还是一个动态的环境。这意味着组件可以在这个环境中动态插拔,这有助于软件功能的无缝切换。这一功能也可称为动态跨平台。<br><br>BOS可以被称为一个组件系统。它定义了组件规范,并给出了组件的使用环境。但更准确的讲,BOS是一个基于组件技术的通用软件框架。<br><br>BOS可以使用在几乎所有类型的应用中。虽然目前版本的BOS是基于.NET Framework完成的,但其背后的理论却是通用的—提供一个纯粹的组件应用环境,让基于该环境的软件完全组件化。<br><br><br>二、 规范<br>2.1 组成<br>BOS由BOS核心和BOS组件构成。BOS核心即是BOS组件的动态应用环境。为了让基BOS的软件达到完全组件化的目的,BOS还包括一个通用目的的可执行程序。这个可执行程序读取一个配置数据文件,从中获取相应的初始化数据,其中包括该应用使用到的组件信息。<br><br>此外,BOS还包括一个通用编辑器BOS Editor,用于为不同的应用快速地编辑配置数据文件。<br><br>2.2 BOS核心<br>BOS核心采取接口/实现分离的设计。BOS核心接口是一个命名为BOS.Center的类。你可以自行为其提供实现,也可以使用BOS源码包中提供的实现BOS.InProcBOSCtr。<br><br>2.3 BOS组件<br>所有的BOS组件都应该遵循接口/实现分离的设计。在实现端还应该为不同的BOS组件提供相应的创建器。组件创建器必须从接口类BOS.Creator_派生。<br><br>2.4 使用BOS<br>下面给出一个简单例子(C#):<br>public interface TestComp<br>{<br> void DoSomething();<br>}<br><br>class TestCompImpl :TestComp<br>{<br> public virtual void DoSomething()<br> {<br> …<br>}<br>}<br><br>class TestCompCreator : BOS.Creator_<TestComp><br>{<br> public virtual TestComp Do( Object[] params )<br> { <br> return new TestCompImpl();<br>}<br>}<br><br>class Program<br>{<br> static void Main(string[] args)<br> {<br> Center center = new CenterImpl();<br> center.Register(new CompID(typeof(TestComp), new TestCompCreator() );<br> TestComp comp = center.Create(new CompID(typeof(TestComp), null ); <br> comp.DoSomething(); <br> }<br>}<br><br>2.5 基于BOS的应用<br>基于BOS的应用并不像2.4所述的那样使用BOS。由于BOS提供了通用目的的AppBOSExe.exe,基于BOS的应用只需要提供组件和数据配置文件即可。其启动通过命令行完成:<br>prompt> AppBOSExe.exe test.boscfg<br><br>建议将配置数据文件命名为.boscfg,并将此类型文件关联到AppBOSExe.exe,从而可以双击配置文件图标以启动应用。<br><br>2.6 配置数据文件和编辑器<br>数据配置文件表征具体的应用。数据配置文件必须满足一定语法格式。你可以参考BOS源码包中的配置数据文件以进一步了解其语法。<br><br>通常情况下,我们通过编辑器来编辑配置数据文件。编辑器以树状图呈现出配置数据。你只需在相应的结点上点击鼠标右键便可以获得相应的命令,进而一步步编辑出所需的配置数据文件。<br><br>编辑器本身也是一个基于BOS的应用。你可以通过命令行启动它,或是将其拖拽到AppBOSExe.exe图标上进行启动。<br><br>2.7 软件要求<br>目前版本的BOS基于.NET Framework 2.0 实现。BOS项目通过Visual Studio 2005 创建。<br><br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值