Questions tagged «entity-component-system»

4
如何在我的代码中避免“经理”
该问题是从Code Review Stack Exchange 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 6年前。 我目前正在为C ++ 重新设计我的实体系统,并且我有很多经理。在我的设计中,我有这些类,以便将我的库联系在一起。关于“经理”类,我听说过很多坏事,也许我没有适当地命名我的类。但是,我不知道还有什么名字。 在我的图书馆中,大多数经理都是由以下类组成的(尽管确实有所不同): 容器-管理器中对象的容器 属性-管理器中对象的属性 在我的图书馆新设计中,我有这些特定的类,以便将我的图书馆联系在一起。 ComponentManager-管理实体系统中的组件 组件容器 ComponentAttributes 场景*-对场景的引用(请参见下文) SystemManager-管理实体系统中的系统 系统容器 场景*-对场景的引用(请参见下文) EntityManager-管理实体系统中的实体 EntityPool-实体池 EntityAttributes-实体的属性(只能由ComponentContainer和System类访问) 场景*-对场景的引用(请参见下文) 场景-将所有经理联系在一起 组件管理器 系统管理员 实体管理器 我当时只是想将所有容器/池放入Scene类本身。 即 代替这个: Scene scene; // create a Scene // NOTE: // I technically could wrap this line …

5
实体组件系统体系结构对象是否按定义定向?
按照定义,实体组件系统体系结构是否面向对象?对我来说,这似乎更具程序性或功能性。我的观点是,它不会阻止您以OO语言实现它,但是以坚定的OO方式实现它并不是惯用的。 似乎ECS会将数据(E&C)与行为(S)分开。作为证据: 这个想法是在实体中没有嵌入任何游戏方法。 和: 该组件包含用于特定目的的最少数据集 系统是具有一组具有特定组件的实体的单一目的功能 我认为这不是面向对象的,因为面向对象的很大一部分是将您的数据和行为结合在一起。 作为证据: 相反,面向对象的方法鼓励程序员将数据放置在程序其余部分无法直接访问的位置。而是通过调用专门编写的函数(通常称为方法)来访问数据,这些函数与数据捆绑在一起。 另一方面,ECS似乎只不过是将数据与行为分开。

2
实体组件系统对解耦/信息隐藏不是很可怕吗?
标题故意是双曲线的,可能只是我对模式的经验不足,但这是我的理由: 实现实体的“通常”或可以说是直接的方法是通过将它们实现为对象并将其子类化为常规行为。这导致了经典的问题“是或EvilTree的子类”。如果我们允许多重继承,就会出现钻石问题。我们可以代替拉的组合功能,并进一步向上层次导致神类,或者我们可以故意留出的行为在我们和类(使他们在极端情况下接口),以便可以实现本身-这会导致如果有一个代码复制。TreeEnemyTreeEnemyTreeEntityEvilTreeSomewhatEvilTree 实体组件系统试图通过将解决这一问题Tree和Enemy对象到不同的组件-比如Position,Health和AI-和执行系统,例如AISystem,根据AI决定改变一个Entitiy的位置。到目前为止,EvilTree还算不错,但是如果可以启动电源并造成损害该怎么办?首先,我们需要一个CollisionSystem和一个DamageSystem(我们可能已经有了这些)。CollisionSystem与进行通信的需求DamageSystem:每次两件事冲突时,CollisionSystem都会向发送一条消息,DamageSystem以便减少健康状况。损坏也会受到通电的影响,因此我们需要将其存储在某个地方。我们是否创建一个PowerupComponent附加到实体的新商品?但是然后DamageSystem需要知道一些它宁愿一无所知的东西-毕竟,有些东西会造成无法获得能量的伤害(例如Spike)。我们是否允许PowerupSystem修改StatComponent与该答案类似的用于损伤计算的?但是现在两个系统访问相同的数据。随着我们的游戏变得越来越复杂,它将变成无形的依赖图,其中组件在许多系统之间共享。在这一点上,我们可以使用全局静态变量并摆脱所有样板。 有解决此问题的有效方法吗?我曾经有过一个想法,就是让组件具有某些功能,例如,给StatComponent attack()它默认情况下只返回一个整数,但是可以在上电时进行组合: attack = getAttack compose powerupBy(20) compose powerdownBy(40) 这不能解决attack必须保存在多个系统访问的组件中的问题,但是如果我有足够的语言来支持它,至少我可以正确键入这些函数: // In StatComponent type Strength = PrePowerup | PostPowerup type Damage = Int type PrePowerup = Int type PostPowerup = Int attack: Strength = getAttack //default value, can be changed by systems getAttack: PrePowerup // these functions …

1
OOP ECS与纯ECS
首先,我知道这个问题与游戏开发主题相关,但是我决定在这里提出这个问题,因为它实际上归结为一个更一般的软件工程问题。 在过去的一个月中,我阅读了很多有关实体组件系统的信息,现在对这个概念相当满意。但是,似乎有一个方面似乎缺少明确的“定义”,并且不同的文章提出了根本不同的解决方案: 这是ECS是否应该破坏封装的问题。换句话说,其OOP风格的ECS(组件是具有状态和行为的对象,它们封装了特定于它们的数据)与纯ECS(组件是c样式的结构,仅具有公共数据,并且系统提供了功能)。 请注意,我正在开发框架/ API /引擎。因此,目标是无论使用它的人都可以轻松扩展它。这包括添加新类型的渲染或碰撞组件之类的东西。 OOP方法的问题 组件必须访问其他组件的数据。例如,渲染组件的draw方法必须访问变换组件的位置。这将在代码中创建依赖项。 组件可以是多态的,这进一步引入了一些复杂性。例如,可能有一个Sprite渲染组件,它会覆盖渲染组件的虚拟绘制方法。 纯方法的问题 由于必须在某个地方实现多态行为(例如,用于渲染),因此它只是外包给了系统。(例如,精灵渲染系统创建一个继承渲染节点的精灵渲染节点,并将其添加到渲染引擎中) 系统之间的通信可能很难避免。例如,碰撞系统可能需要根据任何具体的渲染组件计算出的边界框。这可以通过让他们通过数据进行通信来解决。但是,这会删除即时更新,因为渲染系统将更新边界框组件,然后碰撞系统将使用它。如果未定义调用系统更新功能的顺序,则可能导致问题。存在一个事件系统,该事件系统允许系统引发其他系统可以订阅其处理程序的事件。但是,这仅适用于告诉系统该怎么做,即无效函数。 还需要其他标志。以图块地图组件为例。它将具有大小,图块大小和索引列表字段。瓦片贴图系统将处理相应的顶点数组,并根据组件的数据分配纹理坐标。然而,每帧重新计算整个图块地图是昂贵的。因此,将需要一个列表来跟踪所有更改,然后在系统中对其进行更新。以OOP方式,这可以由图块地图组件封装。例如,SetTile()方法将在调用顶点数组时对其进行更新。 尽管我看到了纯方法的美妙之处,但我真的不明白与传统OOP相比它将带来什么样的具体好处。组件之间的依赖性仍然存在,尽管被系统隐藏了。同样,我将需要更多的类来实现相同的目标。在我看来,这似乎是一种过度设计的解决方案,但这从来都不是一件好事。 此外,我对性能的关注并不那么深,所以面向数据设计和现金遗漏的整个想法对我来说并不重要。我只想要一个好的架构^^ 尽管如此,我阅读的大多数文章和讨论都建议使用第二种方法。为什么? 动画 最后,我想问一个问题:如何在纯ECS中处理动画。目前,我已将动画定义为根据0到1之间的进度操纵实体的函子。动画组件具有一个动画列表,该列表包含一个动画列表。然后,在其更新功能中,它将当前激活的任何动画应用于实体。 注意: 我刚刚读了这篇文章实体组件系统体系结构对象是否按定义导向?可以比我更好地解释问题。尽管基本上是同一主题,但对于纯数据方法为何更好,仍然没有给出任何答案。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.