对于我正在制作的2D游戏(对于Android),我使用的是基于组件的系统,其中GameObject包含多个GameComponent对象.GameComponents可以是输入组件,渲染组件,子弹发射组件等.目前,GameComponents具有对拥有它们的对象的引用并且可以对其进行修改,但GameObject本身只有一个组件列表,并且它不关心组件是什么,只要它们在对象更新时可以更新.
有时组件有一些GameObject需要知道的信息.例如,对于碰撞检测,GameObject将自身注册到碰撞检测子系统,以在其与另一个对象碰撞时被通知.碰撞检测子系统需要知道对象的边界框.我将x和y直接存储在对象中(因为它被几个组件使用),但宽度和高度仅为保存对象位图的渲染组件所知.我想在GameObject中有一个方法getBoundingBox或getWidth来获取该信息.或者一般来说,我想从组件向对象发送一些信息.但是,在我目前的设计中,GameObject不知道它在列表中具有哪些特定组件.
我可以想出几种方法来解决这个问题:
我可以让游戏对象拥有一些重要组件的特定字段,而不是拥有一个完全通用的组件列表.例如,它可以有一个名为renderingComponent的成员变量; 每当我需要获得我刚才使用的对象的宽度时renderingComponent.getWidth().这个解决方案仍然允许组件的通用列表,但它以不同的方式处理它们中的一些,并且我担心由于需要查询更多组件,我最终会有几个特殊字段.有些对象甚至没有渲染组件.
将所需信息作为GameObject的成员,但允许组件更新它.因此,对象的宽度和高度默认为0或-1,但渲染组件可以在其更新循环中将它们设置为正确的值.这感觉就像一个黑客,我可能最终会向GameObject类推送很多东西以方便使用,即使并非所有对象都需要它们.
组件实现一个接口,指示可以查询的信息类型.例如,渲染组件将实现HasSize接口,该接口包括getWidth和getHeight等方法.当GameObject需要宽度时,它会遍历其组件,检查它们是否实现了HasSize接口(instanceof在Java中使用关键字,或is在C#中).这似乎是一个更通用的解决方案,一个缺点是搜索组件可能需要一些时间(但是,大多数对象只有3或4个组件).
这个问题与具体问题无关.它常常出现在我的设计中,我想知道处理它的最佳方法是什么.性能有点重要,因为这是一个游戏,但每个对象的组件数量通常很小(最大值为8).
简短的版本
在基于组件的游戏系统中,在保持设计通用性的同时,将信息从组件传递到对象的最佳方法是什么?
我正在搜索一些库,它实现了在多个游戏中使用的基于组件的实体系统(ECS)框架,并在许多游戏引擎中实现(unity,libgdx等)
我正在scala(ECS roguelike)开始一个小游戏项目,此时我只找到一个名为ashley的java库.
你知道是否存在其他ECS库(在Scala中),或者唯一的方法是在scala(ashley)中使用或重新实现这个库吗?
另一个相关的问题,演员范式和基于组件的实体系统并不是那么遥远,有什么区别?
我知道有函数编程语言(LISP,Haskell等)和OOP编程(Java,C#,Ruby,Python等等),但有没有围绕实体组件编程的概念?
我正在开发一个自定义引擎,我有两个不同的转换类,一个用于2D,一个用于3D.我正在使用#define来选择要使用的转换类,并在逻辑应该相同的位置使用该定义而不是类名.我现在处于一个部分,我希望他们有不同的逻辑,并希望做一个比较分支.我需要做些什么才能让它发挥作用?
class Transform2D;
class Transform3D;
#define TransformClass Transform2D
if(TransformClass == Transform2D)
{
//like this
}
else
{
//like that
}
Run Code Online (Sandbox Code Playgroud)
类型ID适用于此.你怎么处理?
if ( typeid(TransformClass) == typeid(Transform2D) )
{
ittransform->SetRotation(0);
ittransform->SetScale(Vector2D(defaultScale, defaultScale));
}
else
{
ittransform->SetRotation(Vector3f());
ittransform->SetScale(Vector3f(defaultScale, defaultScale, defaultScale));
}
Run Code Online (Sandbox Code Playgroud)