注意:这个介绍是关于实体系统的。但是,即使你不知道它们是什么,或者自己没有实现它们,它也是非常基本的,如果你有一般的Javascript经验,你可能有足够的资格来回答。
我在T =机器博客上阅读有关实体系统的articles。
作者Adam认为实体应该只是一个id,可用于获取它的组件(即实体应该代表的实际数据)。
我选择了所有实体应存储在“一个地方”的模型,我实现此存储的主要嫌疑人是许多人使用的阵列阵列方法,这意味着动态实体ID代表属于实体的组件的索引,而组件按类型分组在“一个地方”(从现在开始我称之为“存储”),我计划以Scene
的形式实施。 Scene
将是一个处理实体组成,存储的对象,并且可以对实体(.addComponent(entityID, component)
等)执行一些基本操作。
我不关心Scene
对象,我很确定这是一个很好的设计,但我不确定是存储的实现。
我有两个选择:
A)使用数组数组方法,其中存储如下所示:
//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是静态,这对于在实体系统本身之外实现游戏循环和其他功能似乎是一件非常好的事情。此外,这意味着系统可以轻松存储他们感兴趣的实体ID数组。显然,entityId变量也是一个字符串,而不是整数索引。
我反对数组数组方法的原因是删除实体会在删除单个实体时更改其他实体ID。
实际的实施细节可能会持谨慎态度,但我想知道哪种方法会更好地表现?
我也感兴趣的事情(请尽可能跨平台,但如果需要,请使用V8作为示例):
undefined
是多少,需要多少钱?我问这个,因为在数组数组方法中,所有内部数组必须具有相同的长度,并且如果实体没有某个组件,则该字段设置为undefined
。答案 0 :(得分:-1)
不要担心数组。它是JavaScript中的一个Object,即没有“真正的”数组,它只是索引是对象属性(字典,散列,映射)的数字“名称”。
这个想法很简单,一个Array有一个length属性,允许循环知道在哪里停止迭代。通过简单地从Array中删除一个元素(记住,它是一个Object),length属性实际上并没有改变。所以......
// create an array object
var array = ['one','two', 'three'];
console.log(array.length); // 3
// these don't actually change the length
delete array['two']; // 'remove' the property with key 'two'
console.log(array.length); // 3
array['two'] = undefined; // put undefined as the value to the property with key 'two'
console.log(array.length); // 3
array.splice(1,1); // remove the second element, and reorder
console.log(array.length); // 2
console.log(array); // ['one','three']
if(array['two'])
检查字段是否存在,因为字段实际上可以保存 undefined,null,0,“”,false 的虚假值并评估为false 。请务必查看if('two' in array)
; for(key in array)
循环时总是使用if(array.hasOwnProperty(key))
,因此您不会迭代原型的属性(以某种方式说明父级)。此外,构造函数创建的对象也可以使用'constructor'键循环。