Articles of 实体系统

什么组件应该持有布尔攻击和向量目标?

我很难考虑哪些组件应该保存攻击和目标数据。 在下面的代码中,组件持有一个我想消除的冗余数据。 public class PlayerComponent implements Component { public boolean attack = false; public Vector2 target = new Vector2(); } public class PoliceComponent implements Component { public boolean attack = false; public Vector2 target = new Vector2(); } public class CriminalComponent implements Component { public boolean attack = false; public Vector2 target = new Vector2(); […]

如何将实体和组件的概念添加到等轴测图地图?

为了得到一些SpriteKit的实践,我创建了一个实体和组件。 我创建了一个SKNode子类( IsometricMapNode ),它呈现一个等轴测图。 它通过SKSpriteNode自身添加SKSpriteNode ( TileSpriteNode )子类来实现。 地图的数据存储在管理IsometricLayer和Tile对象的平台不可知类IsometricMap中。 地图可以执行加载TMX文件和生成包含信息的瓦片(瓦片types,纹理名称等)。 然后将地图传递给上述IsometricMapNode并显示。 一切工作正常,但后来我读了关于GKEntity ,我想知道如果我能介绍实体的概念到我的代码。 我想知道如果我的地图中的每个瓷砖应该是一个实体,然后将获得一个渲染组件,也许物理组件或粒子组件。 我不明白的是:我的模型类Tile成为GKEntity ,还是它的视觉表亲TileSpriteNode ? 还是仅仅是哲学? 如果Tile是实体,那么我的地图的用户会为它添加新的实体,希望能够附加一个渲染组件。 如果我保留我的Tile模型类,地图将从这个类内部创建实体,添加一些标准组件(主要是渲染),并允许用户稍后更改这些组件。 这是有道理的吗? 🙂

如何在实体组件系统中呈现?

我目前正在使用一个实体组件系统的Java游戏。 游戏目前在游戏循环中有两个独立的update()和render()方法,但是这似乎不适合我的实体组件系统。 据我所知,ECS中的每个系统都有一个更新方法,但是怎么说呢,一个在屏幕上绘制精灵的渲染系统呢? 渲染如何与ECS一起工作? 一个想法可能是在屏幕上绘制的系统实现一个RenderSystem接口,以便它们只用于渲染方法,但我从来没有见过这样的事情。 有没有这样做的某种方式?

你将如何处理实体组件系统中的不同级别types?

我目前正在利用Libgdx(Java)开发一个Ashley实体组件系统的游戏。 在游戏中,你将能够在行星上行走(2D而不是3D),在星系中飞行并在系统之间穿行。 这些都是不同types的层次,都需要处理和呈现不同。 所以我的问题是,你将如何区分这些types(例如在渲染器中),我应该为渲染器中的每种types添加一个案例还是以某种方式分割它?

实体是否应该根据组件签名自动注册到系统?

我看到所有在自动注册基本组件的实体上的优势。 如果实体具有Renderable组件,则应将其注册到可呈现系统使用的列表中。 如果一个实体有一个物理组件,它将被注册到物理系统使用的物理实体列表中。 但是,除此之外,假设我们有一个由Physics和Renderable组件创建的实体。 我完全理解ECS通常如何处理这个案例, 如果有一个系统对具有Physics和Renderable组件的实体起作用,则大多数实体组件系统(ECS)会自动将该实体注册到该系统,因为签名匹配(在其他框架中,如果方面匹配等) 。 此外,如果您在运行时从实体添加任何组件,则大多数ECS将循环遍历所有系统,并尝试在其新签名符合系统要求(同样在删除组件时取消注册实体)的情况下注册此实体。 在实践中,这似乎有许多缺点(特别是谈论超过1个组件的签名自动匹配系统的情况): 1.具有一组特定组件的所有实体将自动注册到程序员可能没有预期/记住的系统 。 也许有意义的是,具有物理和视觉组件的实体应该由物理 – 视觉系统来操作,但也许不是。 每当我们向实体添加组件时,可能很难预见它将注册到的所有系统,并可能产生意想不到的后果(类似于删除组件)。 如果我们有多个人在创建系统,那么意想不到的后果的可能性就会上升。 [运行时的逻辑错误,可维护性问题] 2.如果我们有像上面这样的符合签名的实体,但我们不想将其注册到特定的系统,最好的解决scheme是为实体添加一个标签。 然后,我们会添加一个排除在系统的方面,它会对它进行操作 – 但这耦合了EntityCreators和系统注册[高耦合]的行为 。 否则,我们会检查系统更新循环中每个实体上的dynamic标签,并在某些标签上执行noop [不需要的工作,不完全是纯粹的ECS] 3.我们需要创建一个位掩码系统或其他等价物来管理签名,并且每当实体发生变化时,总是循环遍历几乎所有的系统。 当然,这一切都取决于实现,但总是需要某种forms的循环检查。 在许多情况下,对于复杂的方面或处理大量系统时,这可能变得非常低效,并限制了如何构建您的方面/系统。 [很多工作] 4.有时ECS的实现方式允许系统访问所有实体组件,而这些组件可能或可能不是系统要求的一部分。 [容易打破封装] 。 现在这可能不是什么大问题,如果每个人都在“纯粹”ECS的错综复杂的问题上,但是考虑到围绕types转换实体和运行时检查实体标签的问题的数量,它的共同性足以导致系统中的快捷方式并创建更多[运行时错误] 。 真的,问题1,2和4产生了类似于鸭子打字和dynamic铸造一般出现的问题。 而不是自动注册实体匹配签名(通过整个实体或通过节点)的系统,它不是更types安全和可维护,但可扩展,直接注册在EntityCreators / EntityModifier类的组件袋节点? 如果我们创建的实体具有一个物理组件和一个可渲染组件,并且在我们的脑海中匹配一个物理可编辑对象所做的事情,那么我们将添加一个名为PhysicsRenderable的组件,该组件被注入到我们的物理和可渲染组件中。 通过明确地说,我们的实体匹配我们认为可以物理调配的人应该做的事情,我们解决1 。 如果它与我们所认为的PhysicsRenderable不相符,那么我们只添加Physics和Renderable组件,解决2 。 注意:如果我们希望在PhysicsRenderable实体上工作的系统更新我们的系统,我们必须记住将其注册为PhysicsRenderable,但是这具有与1相反的效果,但与相反的情况相比,这可以更容易地进行debugging和修复。 然后,我们的实体将具有组件[物理,可渲染,物理可以]。 此外,我们的系统将只注册到一种types(物理,可渲染,物理可编辑),然后注册实体的逻辑将变得比使用3中描述的位掩码或其他方法简单得多。 而且因为我们明确地使用PhysicsRenderable构建了实体,所以它可以作为我们的系统中遍历的节点列表的types,在PhysicsRenderables上运行(不再遍历整个实体,解决问题4 )。 添加细节:删除另一个组件中实体的组件,即从PhysicsRenderable的实体中删除Physics,需要一个额外的侦听器来注销PhysicsRenderable组件,但这与其他组件的情况没有多大区别。已经在ECS中完成了。 现在我意识到这样做违背了一些人可能认为是ECS(自动签名注册)的核心原则,但是它仍然使用了很多其他的核心思想(自动将实体注册到处理那些预期对那些实体)。 这种方法有更多的缺点,我没有看到? 是否有任何ECS使用这种需要对实体进行明确签名的框架?

在deviseECS时,我应该如何轮询组件状态变化?

我正在实施一个ECS,并陷入困境。 假设我的主循环是类似的(超级简化,下面的所有代码都是伪代码) while (true) { // timing logic in here somewhere for (GameSystem system : systems) { for (GameEntity entity : entities) { system.update(entity); } } } 组件需要更新它们的状态,但是更新状态到底是怎样的模糊。 假设我有一个InputComponent基types。 可以有很多InputComponenttypes,键盘,控制器等。 我 (作为游戏引擎)并不在意你是按下W键的意图向上移动,还是你按Spacebar键跳转。 这不在我所关心的范围之内。 我所关心的是意图。 我很在乎你想要移动,或跳转,但不在乎如何生成命令。 如何生成该命令由InputComponent决定。 否则,我将不得不弄脏我的系统代码类似的东西 class MovementSystem { void update(GameEntity entity) { if (entity.getSettings().isUsingKeyboardInput()) { if (entity.getKeyboardInput().isSKeyPressed()) { moveDown(); } else if (entity.getKeyboardInput().isWKeyPressed()) […]

如何管理游戏组件及其属性?

目前我正在使用iPhone的cocos2d。 我想让我的游戏结构化和结果性。 如何管理所有的游戏组件? 我的意思是什么游戏组件? 游戏组件是例如地形或任何其他物体,如在场景中绘制的角色。 这些组件具有像“让我们清理那个地方”或类似的东西的属性和职责。 所以实际上我想包装一个组件的所有属性,使代码可重用。 想想地形。 前方可能有地形。 在这个地形的背后还有另外一个地形,例如山丘,它仍然是地形,但是也许还有另一种颜色。 我如何在cocos2d中完成这项工作? 在我的场景中,通常会画出地形的绘制方法。 但是如果我把所有的东西都画在这个方法上,会让人感到困惑。 创建地形类的对象并将其添加到将自动绘制地形的场景将会很酷。 我怎么做? 什么是地形类的父类?

如何保持input系统和graphics系统分离?

我想保持input系统和graphics系统分开,但由graphics组件创建的窗口处理程序使一切真的很难。 我应该如何处理这种情况?

如何关联实体组件系统中的实体(Artemis)

我想在ECS体系结构中使用Artemis框架实现两个实体之间的关联,Artemis框架非常适合我处理组件,实体和系统。 我有一个实体“帝国”(帝国ID,研究技术等几个组成部分),我希望在两个帝国(战争,和平)之间建立“外交”。 我可以通过哪种方式实施ECS架构? 我知道联合组件,但不涉及实体。 谢谢

基于组件的体系结构中的组件inheritance之后未使用的方法?

我有一个GameObject类,其中包含组件,如: 渲染 相机 行为 刚体 首先, 我从具有Update()方法的Componentinheritance了它们 ,并且在每个游戏对象的每个组件上调用每一帧。 但后来我注意到,**渲染器和相机的更新方法是未使用**。 (像RenderData和CameraData这样的类是由基元分离出来的,在创建这些组件时,这些数据的指针被发送给GraphicsEngine,它将每帧处理它们。) 所以有一个未使用的方法是不好的。 所以我创建了一个DynamicComponent类 ,它inheritance了Component,而Behavior&Rigidbody类是从它inheritance的。 我将Update()从Component移动到了DynamicComponent,并且在gameobjects中有两个容器 : 组件(对于直接从组件inheritance的组件) dynamic组件(用于从D.Compinheritance的组件) 而每一帧我只称为DynamicComponents的更新()。 现在我有另一个问题。 有Behavior类,其中应该是一个Start()方法 ,在场景完全初始化时在每个Behavior上调用它。 这意味着我应该在游戏对象中有一个Components,D.Components和一个Behaviors容器 。 这对我来说很不好 有一个组件类,与开始(),更新()等非常简单,使一个非常干净的代码,但这意味着只有less数派生类实现其虚拟方法。 我该怎么办?