注意:这个介绍是关于实体系统的。但是,即使您不知道这些是什么,或者自己没有实现它们,它也是非常基础的,如果您有一般的 Javascript 经验,您可能有足够的资格来回答。
我正在T=machine 博客上阅读有关实体系统的文章。
作者 Adam 建议实体应该只是一个 id,可用于获取它的组件(即实体应该表示的实际数据)。
我选择了所有实体都应该存储在“一个地方”的模型,我实现这种存储的主要嫌疑人是许多人使用的数组数组方法,这意味着动态实体 id 表示组件所属的索引到一个实体,而组件在那个“一个地方”中按类型分组(从现在起我将称之为“存储”),我计划将其实现为Scene
. 这Scene
将是一个处理实体组合、存储并可以对实体(.addComponent(entityID, component)
等)进行一些基本操作的对象。
我不关心Scene
对象,我很确定这是一个很好的设计,但我不确定存储的实现。
我有两个选择:
A)使用 array-of-array 方法,其中存储如下所示:
//storage[i][j] - i denotes component type, while j denotes the entity, this returns a component instance
//j this is the entity id
[
[ComponentPosition, ComponentPosition, ComponentPosition],
[ComponentVelocity, undefined, ComponentVelocity],
[ComponentCamera, undefined, undefined]
]
//It's obvious that the entity `1` doesn't have the velocity and camera components, for example.
B)将存储对象实现为字典(技术上是 Javascript 中的对象)
{
"componentType":
{
"entityId": ComponentInstance
}
}
字典方法意味着实体 id 是static,这对于在实体系统本身之外实现游戏循环和其他功能似乎是一件非常好的事情。此外,这意味着系统可以轻松地存储他们感兴趣的实体 id 数组。entityId 变量显然也可以是字符串,而不是整数索引。
我反对array-of-arrays方法的原因是删除实体会在删除单个实体时使其他实体ID发生变化。
实际的实现细节可能很谨慎,但我想知道哪种方法在性能方面会更好?
我也感兴趣的事情(请尽可能跨平台,但如果需要,请以 V8 为例):
- 访问属性时的开销有多大,这是如何实现的?可以说他们正在从本地范围内访问。
- 内存中有什么
undefined
,需要多少?我问这个,因为在数组数组方法中,所有内部数组必须具有相同的长度,并且如果实体没有特定组件,则该字段设置为undefined
.