表示和实现实体组件系统的方法有很多种,但这是对一种方法的解释。请记住,没有实体/组件/系统架构的具体定义,因此这只是一种实现。
我将为可能会帮助您的实体/组件/系统架构引入一个类比。让我们考虑一个像钥匙这样的实体。
实体
按键也有牙齿(深蓝色)。我们实体密钥的牙齿是组成它的组件。您可以通过实体的ID来区分实体,即使它们具有相同的牙齿。那么钥匙适合什么呢?锁 锁是我们的系统。例如,运动系统。
系统
仅当我们的钥匙的位置和速度都有齿时,锁才起作用。该系统仅处理具有位置和速度的实体。设置这些系统如何识别要处理的实体的方法有多种,但是一种方法是使用long
。每个位都保留用于组件类型。对于我们的示例,假设使用4位类型而不是64位长。我们的示例实体将具有所有可用的组件。所以关键是1111
。然后,系统正在寻找具有的任何实体11--
。(-
表示不在乎,因为运动不在乎精灵或健康状况)。它可以通过简单的AND
操作检查实体。因此,我们的实体匹配if ((1111 & 1100) == 1100)
。如果我迷路了,请查看有关按位运算的更多信息。
如您所见,系统可以访问外部资源。他们可以访问时间,图形,声音等。它们只是一次只需要一把钥匙并处理数据的小型处理器。您会看到运动系统采用速度,增量时间和位置。然后进行一些计算并将结果存储回原位。
实体密钥确实很容易生成。您可以随意添加或删除它们。实体不在乎,这只是对组件进行分组和保存的一种方式。组件之间没有相互依赖性。当系统在组件上运行并使用来自一个组件的数据来更新另一个组件时,就像我们的运动示例一样,组件之间的交互最接近。
让我们看一下另一个系统来帮助巩固这个想法:
这是我们的绘图系统。它寻找匹配的组件1-1-
。该实体之所以匹配,是因为:((1111 & 1010) == 1010)
此外,通过在其位置绘制实体精灵,您可以看到该系统将信息输出到屏幕。
好,再说一遍 让我们看一下另一个实体,看看它到目前为止如何适合我们的示例。
如您所见,此实体具有较少的附加组件。通过查看它确实具有的组件,看起来它可能像石头一样是静态物品。它只是有一个位置和一个精灵。它不会移动,也不会受到任何健康变化的影响。该实体将产生密钥1010。那么,什么系统在该实体上运行?让我们检查:
反对我们的运动系统:
((1010 & 1100) != 1100)
不。好像运动系统不在乎此实体,因为它没有必需的组件。
针对我们的绘图系统:
((1010 & 1010) == 1010)
嘿,这是一个匹配。该实体将由绘图系统进行操作。绘制系统将在定义的位置绘制精灵。
希望您能看到现在添加另一个将采用我们的组件并对其进行操作的系统将是多么容易。让我确保我已经解决了您的问题:
如果多个系统需要访问同一组件怎么办?数据应该存放在哪里?
通常,系统一个接一个地运行。他们处理所有符合其要求的实体,然后下一个系统执行相同的操作,依此类推。数据与实体共存。系统中不应该存储任何东西,它只是一个可以转动的锁,关键是信息保留并在锁之间移动的位置。
如何构造实体?系统本质上与组件相关联吗?如果要引入一些新组件,是否还必须引入新系统或修改现有系统?
实体只是组件袋。它们具有唯一的ID和组件列表。系统仅以上述方式绑定到组件。您可以拥有没有可在其上运行的系统的组件,但这毫无意义。同样,您可以拥有正在寻找没有实体拥有的组件的系统。这没有什么意义,因为他们可能只是在等待创建与其锁匹配的实体。因此,是的,如果您引入一个新的组件,那么您将希望创建一个利用该组件的系统。否则,您只是在钥匙上增加了不存在的锁齿。
如果我的实体只是一个id,我怎么知道我的机器人实体需要移动或渲染并因此被某些系统修改?
我想我用long
定义实体中包含的组件的键的想法来回答这个问题。您知道因为钥匙适合锁。
!那是一个漫长的帖子!(或者至少从我的大型显示器看来是如此。)