Questions tagged «component-based»

基于组件的设计依赖于将业务对象和游戏对象的多个逻辑属性分离为仅用于特定任务的小型组件。游戏对象通常被建模为通过将“现实世界”对象聚合在一起并允许特殊对象从常规对象继承来重现“真实世界”对象的属性和行为,而基于组件的设计则依赖于组成而非继承。

2
基于组件的系统在线资源
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 2年前关闭。 我一直在考虑在游戏中采用基于组件的方法。其他人是否有任何体面的参考资料或示例实现方式将有助于使这种过渡变得容易一些?

2
通常如何在面向组件的系统中构建物理或图形组件?
我花了最后48个小时来阅读对象组件系统,并觉得我已经准备好开始实施它。我已经创建了基本的Object和Component类,但是现在我需要开始创建实际的组件,我有点困惑。当我用HealthComponent或基本上只是属性的东西来考虑它们时,这是很有意义的。当它作为物理/图形学组件更为通用时,我会有些困惑。 到目前为止,我的Object类是这样的(如果您注意到我应该进行的任何更改,请告诉我,这仍然是新的)... typedef unsigned int ID; class GameObject { public: GameObject(ID id, Ogre::String name = ""); ~GameObject(); ID &getID(); Ogre::String &getName(); virtual void update() = 0; // Component Functions void addComponent(Component *component); void removeComponent(Ogre::String familyName); template<typename T> T* getComponent(Ogre::String familyName) { return dynamic_cast<T*>(m_components[familyName]); } protected: // Properties ID m_ID; Ogre::String …

2
基于组件的实体系统中的游戏状态和输入处理
我的问题是: 如何在我的实体系统中处理游戏状态,而又不保留周围的游戏状态对象堆栈? 因此,我的实体系统的设计意味着,例如,当某个实体需要注册输入事件时,输入组件将调用输入系统,并说“为此输入注册此实体”。一切都很好,但是,如果您将游戏状态的概念(例如暂停屏幕)加入其中,那么确定实体是否处于当前状态并应接收输入就变得很困难。 我可以扩充输入组件/系统,使其说“在处于这些游戏状态时为此输入注册此实体”,但这要求每个实体都知道将在其中使用哪个状态,这可能并不明显。同样,在每个注册的输入(以及其他使用回调的系统)周围保留游戏状态列表听起来并不太有效。 我有另一个想法,因为将有一个代表游戏状态的实体,将其标记为已禁用,然后在生成输入事件时检查该实体不是已禁用游戏状态实体的后代。为每个回调计算父级似乎很昂贵。 另一个想法是让所有系统针对当前状态存储其数据密钥,这样,在生成输入时,目标实体甚至都不是候选对象。但是,这确实损害了允许处于不同状态的实体之间进行通信的能力(对于暂停屏幕而言,这并不是什么大问题,但请考虑Oblivion / Skyrim中的锁定选择)。 我唯一的另一个想法是让所有组件处理状态更改事件并与相关系统进行通信以禁用其已注册的任何内容,并在切换回此状态时重新启用它。 第二个(将对象标记为已禁用)和第四个(使每个组件都处理状态更改)似乎是我的最佳想法,但是没有一个想法特别出色。 还有其他人对此有其他想法吗? 编辑当我谈论输入专门在这个问题上,它可能意味着能够发送消息/事件的实体,如碰撞,定时器事件等的任何系统...

3
为什么将方法存储在实体和组件中是一个坏主意?(以及其他一些有关实体系统的问题。)
这是我对这个问题的回答,但是我回答了一个更具体的主题。 这个答案使我比本文更好地理解了实体系统。 我读了 有关实体系统的文章(是的),它告诉我以下内容: 实体只是一个id和一组组件(文章说,将实体存储在组件中不是一种好方法,但没有提供替代方法)。 组件是数据片段,它们指示可以对特定实体执行的操作。 系统是“方法”,它们对实体上的数据进行操作。 在许多情况下,这似乎确实可行,但是有关组件仅仅是数据类的部分让我感到困扰。例如,如何在实体系统中实现Vector2D类(位置)? Vector2D类保存数据:x和y坐标,但是它也具有方法,这对于其有用性至关重要,并且可以将类与仅包含两个元素的数组区分开。实施例的方法有:add(),rotate(point, r, angle),substract(),normalize(),和所有其他的标准,有用的和绝对需要的方法该位置(其是对的Vector2D类的实例)应该有。 如果该组件只是一个数据持有者,它将无法使用这些方法! 一种可能弹出的解决方案是在系统内部实现它们,但这似乎非常违反直觉。这些方法是我现在要执行的事情,要使它们完整并可以使用。我不想等待MovementSystem读取一些昂贵的消息,这些消息指示它对实体的位置进行计算! 并且,该文章非常清楚地指出,只有系统才应该具有任何功能,而对此的唯一解释是“避免OOP”。首先,我不明白为什么我应该避免在实体和组件中使用方法。内存开销实际上是相同的,并且当与系统耦合时,它们应该非常容易实现并以有趣的方式组合。例如,系统只能向知道实现本身的实体/组件提供基本逻辑。如果您问我-这基本上是从ES和OOP那里获得的好处,根据本文的作者所说,这是无法完成的,但是对我来说,这似乎是一种好习惯。 这样想吧;游戏中有许多不同类型的可绘制对象。普通的旧图像,动画(update(),getCurrentFrame()等),这些原始类型的组合以及所有这些都可以简单地为draw()渲染系统提供一种方法,然后该方法无需关心实体的sprite是如何实现的,关于界面(绘制)和位置。然后,我只需要一个动画系统,该系统将调用与渲染无关的特定于动画的方法。 还有另一件事……关于存储组件,真的有数组的替代方法吗?除了实体类中的数组,我看不到要存储组件的其他地方。 也许这是一个更好的方法:将组件存储为实体的简单属性。例如,位置组件将粘贴到entity.position。 的唯一其他方法是有某种奇怪的查找表的内部系统中,引用不同的实体。但是,这似乎非常低效的,更复杂的比在实体只需存储组件来开发。

2
设计基于组件的游戏
我正在写一个射击游戏(例如1942年,经典的2D图形),我想使用基于组件的方法。到目前为止,我考虑了以下设计: 每个游戏元素(飞艇,弹丸,加电,敌人)都是一个实体 每个实体都是一组可以在运行时添加或删除的组件。例如位置,雪碧,健康,IA,损坏,边界框等。 这个想法是飞艇,弹丸,敌人,威能不是游戏类。实体仅由其拥有的组件定义(并且可以随时间变化)。因此,玩家飞艇从Sprite,Position,Health和Input组件开始。上电有Sprite,Position,BoundingBox。等等。 主循环管理游戏“物理”,即组件之间如何交互: foreach(entity (let it be entity1) with a Damage component) foreach(entity (let it be entity2) with a Health component) if(the entity1.BoundingBox collides with entity2.BoundingBox) { entity2.Health.decrease(entity1.Damage.amount()); } foreach(entity with a IA component) entity.IA.update(); foreach(entity with a Sprite component) draw(entity.Sprite.surface()); ... 组件在主C ++应用程序中进行了硬编码。实体可以在XML文件中定义(lua或python文件中的IA部分)。 主循环对实体并不太在意:它仅管理组件。该软件设计应允许: 给定一个组件,获取它所属的实体 给定一个实体,获取类型为“ type”的组件 …

6
游戏组件,游戏管理器和对象属性
我正在努力使基于组件的实体设计成为现实。 我的第一步是创建可以添加到对象中的各种组件。对于每种组件类型,我都有一个管理器,该管理器将调用每个组件的更新功能,并根据需要传入诸如键盘状态之类的信息。 我要做的下一件事是删除对象,并让每个组件都带有一个ID。因此,对象是由具有相同ID的组件定义的。 现在,我在想我不需要所有组件的管理器,例如,我有一个SizeComponent,它只是一个Size属性)。结果,SizeComponent它没有更新方法,并且管理器的更新方法不执行任何操作。 我的第一个想法是要有一个ObjectProperty组件可以查询的类,而不是将它们作为组件的属性。因此,一个对象有许多ObjectProperty和ObjectComponent。组件将具有查询对象属性的更新逻辑。管理者将管理调用组件的更新方法。 在我看来,这似乎是工程过度,但我认为我无法摆脱这些组件,因为我需要让管理人员知道哪些对象需要哪种组件逻辑才能运行(否则,我只会删除该组件)并将其更新逻辑推入管理器)。 难道这(有ObjectProperty,ObjectComponent和ComponentManager班)在工程? 有什么好的选择?


2
实体/组件系统和UI“实体”
我对实体/组件系统仍然很满意。我发现,由于我具有用于绘制精灵(或精灵表)和处理输入(鼠标/触摸点击)的有用组件,因此我自然希望重用这些组件来创建UI组件(例如按钮,例如,级别选择屏幕)。 这让我感到非常奇怪。我一直将实体理解为“游戏模型”,例如玩家,敌人,道具等。从代码重用的角度来看,为UI重用组件是很有意义的。 UI / GUI关注点如何(以及在​​哪里)适合实体/组件系统? (注意:此问题与平台无关,因为它适用于多种平台/语言)


4
如何使用基于组件的架构设计有效的游戏对象交互方案?
这是一个设计问题。我敢肯定,这可以进一步推广,但是我很难过。我想知道游戏对象交互的设计-这是我的示例(二维拼图平台)。 假设玩家正在尝试逐步升级。有许多可以指向不同方向的灯。这是这些灯光对象如何相互作用的示例。 一盏灯投射出一个平台,使玩家可以越过空隙 一盏灯会降低其触摸的任何物体的摩擦系数,另一盏灯会增加它的摩擦系数。 一盏灯使所有灯的效果无效,这将使平台在该灯打开时消失,并使摩擦修饰符无效。 等等... 使用组件体系结构时解决此问题的最佳方法是什么?每个主要对象的组件似乎都是显而易见的,而且是一种清晰的方法来定义其对环境的影响。一个用来“解决”交互作用的类(好像这样很快就会变得一团糟)?使用装饰器模式为在给定时间进行交互的对象创建组合对象?一个适合这种情况的数据结构? 另外,将音频连接到这些交互吗?似乎将音频连接到系统就像连接其他属性一样,例如可见性或播放器移动/碰撞。 显然,随着添加更多组件,如果有一个健壮的系统可以进行少量修改就可以处理新组件,那将是很好的选择,但是我不熟悉如何进行此设计。 其他信息:我使用的引擎是一个名为IceCream的XNA引擎。

3
组成重的OOP与纯实体组件系统?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 我承认,我犯了过度使用甚至滥用继承的罪过。我上OOP课程时所做的第一个(文字)游戏项目远比“门”和“一扇门的房间”,“两扇门的房间”中的“锁门”和“解锁门”有关,以此类推。 通过最近我从事的(图形)游戏,我认为自己已经学到了教训,并限制了继承的使用。但是我注意到问题很快开始出现。我的根类开始越来越膨胀,而我的叶类中充满了重复的代码。 我以为我还是在做错事,在网上查询之后,我发现我并不是唯一遇到此问题的人。经过一些深入的研究,我最终才发现了实体系统(请参阅:googlefu) 当我开始阅读它时,我能够看到它能够多么清晰地解决我的带有组件的传统OOP层次结构所遇到的问题。这些是一读。当我偶然发现更多……“激进”的ES方法时,例如T-machine上的方法。 我开始不同意他们使用的方法。一个纯粹的组件系统似乎要么过大,要么不直观,这可能是OOP的优势。作者甚至说ES系统与OOP相反,尽管它可以在OOP中使用,但实际上不应该。我并不是说这是错误的,但是我只是觉得自己不想实施一个解决方案。 因此,对我来说,为了解决我在帖子开头所遇到的问题,而又不违背我的直觉,那就是仍然使用层次结构,但是它不会像我以前使用的那样是一个整体的层次结构,而是一种多片的(我找不到与单片相反的单词),它由几棵较小的树组成。 下面的示例说明了我的意思(这受我在《游戏引擎体系结构》第14章中找到的示例的启发)。 我会有一棵小树供车辆。根车辆类别将具有渲染组件,碰撞组件,位置组件等。 然后,坦克(车辆的子类)会从中继承这些组件,并被赋予自己的“加农炮”组件。 角色也是如此。角色将拥有自己的组件,然后让Player类继承它,并被赋予Input控制器,而其他敌人类将从Character类继承并被赋予AI控制器。 我真的看不到这种设计有任何问题。尽管没有使用纯的实体控制器系统,但是冒泡效果的问题和大根类的问题是通过使用多树层次结构解决的,繁重的代码复制叶子的问题也消失了,因为叶子没有有任何代码开始,只有组件。如果需要对叶级别进行更改,则就像更改单个组件一样简单,而不是将代码复制粘贴到任何地方。 当然,像我一样没有经验的人,当我刚开始使用单一层次结构,繁重的继承模型时,我没有看到任何问题,因此,如果我当前正在考虑实现的模型存在问题,我不会能够看到它。 您的意见? PS:我正在使用Java,因此无法使用多重继承来实现此功能,而不是使用常规组件。 PPS:组件间通信将通过相互链接相关的组件来完成。这将导致耦合,但是我认为这是一个不错的权衡。

3
与外部组件管理者一起组织实体系统?
我正在为自上而下的多人2D射击游戏设计游戏引擎,我希望该引擎可以合理地重用于其他自上而下的射击游戏。目前,我正在考虑应如何设计其中的实体系统。首先,我想到了这一点: 我有一个叫做EntityManager的类。它应该实现一种称为Update的方法,以及另一个称为Draw的方法。之所以将Logic和Rendering分开是因为,如果运行独立服务器,则可以省略Draw方法。 EntityManager拥有BaseEntity类型的对象列表。每个实体都拥有一个组件列表,例如EntityModel(实体的可绘制表示),EntityNetworkInterface和EntityPhysicalBody。 EntityManager还拥有一个组件管理器列表,例如EntityRenderManager,EntityNetworkManager和EntityPhysicsManager。每个组件管理器都保留对实体组件的引用。有多种原因将此代码移出实体自己的类,而改为集体进行。例如,我使用游戏的外部物理库Box2D。在Box2D中,首先将实体和形状添加到一个世界(在本例中为EntityPhysicsManager拥有),然后添加碰撞回调(将在我的系统中分派给实体对象本身)。然后,您运行一个函数来模拟系统中的所有内容。我发现很难找到比在这样的外部组件管理器中更好的解决方案。 实体创建是这样完成的:EntityManager实现方法RegisterEntity(entityClass,factory),该方法注册如何创建该类的实体。它还实现了CreateEntity(entityClass)方法,该方法将返回BaseEntity类型的对象。 现在出现了我的问题:如何将对组件的引用注册到组件管理器?我不知道如何从工厂/关闭处引用组件管理器。

1
如何在实体/组件系统中处理物料
我的E / C实现是一种基本的实现,其中实体只是ID,组件是数据,系统根据数据进行操作。现在,我在处理对象材质和渲染时遇到了麻烦。对于简单的objetc,我有一个ModelComponent与绑定的RenderSystem,ModelComponent具有渲染系统使用的顶点缓冲区ID。一个简单的对象MaterialComponent可能具有颜色或镜面反射强度等,但是我希望它具有足够的灵活性,以允许多个渲染过程和一般的“效果”,而这些效果不如的简单变量那么容易MaterialComponent。 为了解决这些问题,我想出了两种解决方案: 1-超通用材料组件 像这样: struct Material : public Component { ShaderData* shader; std::vector<std::pair<std::string, boost::any>> uniforms; [...] }; 在渲染系统中,我将循环并将制服传递给着色器。我想这会很慢,但对于我的目的来说足够快了。 2-另一层抽象,MaterialData 有一个包装特定材料的类,该类可以由任何专门的材料继承,基类将具有类似的东西,void set_shader_constants(ShaderData* d)但是实现取决于每个类,并且MaterialComponent将具有一个指向MaterialData对象的指针。 我不确定我会选择哪种方法,但是这些方法都不涉及多次通过或其他复杂的渲染技术。 关于如何做到这一点的任何想法?

2
实体系统框架中的图块地图?
我一直在阅读实体系统框架,尤其是Artemis。我正在尝试确定是否适合我。我严格从事基于图块的2d像素艺术游戏,而且我认为它们永远不会占用大量资源。过去,我一直使用标准OOP进行大量继承。 我现在对实体系统框架的理解(我不确定是否完全掌握): 实体不过是ID的 组件不过是添加到实体组件池中的哑数据 系统是附加到世界的更新功能,用于处理与系统组件签名匹配的每个实体 如果我的理解是正确的,那么在概念上很难在此框架中添加图块图和AI行为树。我将来会问有关AI的问题。 是否应在此框架中内置图块地图?还是应该将其分开放置以使其易于使用tilemap编辑器生成? 如果应该将tilemap内置到此框架中,那么每个tile都是不同的实体吗?和tilemap一个系统?还是tilemap本身就是继承了继承关系的单个实体? 如果tilemap足够精细,那么与外部tilemap碰撞检测实体的最佳方法是什么? 我了解我列出的多个选项可能是正确的,但是如果有人过去这样做过,他们也许可以使我感到困惑。也许还有我没有想到的另一种选择? 谢谢。

3
基于组件的设计中的输入处理
我知道这个问题已经问过几次了,但是我仍然不确定如何在基于组件的引擎中实现输入处理。 我使用的基于组件的设计基于T = Machine的博客系列以及Artemis(其中实体只是id)。 实现输入处理时,我有三个主要想法: 输入组件将保存其感兴趣的事件。输入系统会将键和鼠标事件转换为游戏事件,并使用输入组件在实体之间循环,如果它们对事件感兴趣,则输入系统将采取适当的措施。该动作将被硬编码到输入系统。 没有输入组件。您可以将具有特定事件的实体注册到输入系统。输入系统然后将消息(具有实体ID和事件类型)发送给其他系统,以便它们可以采取适当的措施。或与第一种情况一样,这些动作将被硬编码到输入系统中。 与第一种方法类似,该组件将包含事件到函数(即std::map<std::function>)的映射,而不是对输入系统的动作进行硬编码,输入将调用该函数。这具有能够将同一事件耦合到不同动作的附加效果。 您会建议上述任何一种方法,还是对我实现灵活的输入处理系统有任何建议?另外,我还不熟悉多线程,但是也欢迎任何使实现线程友好的建议。 注意:我希望实现能够满足的另一个要求是,我能够将相同的输入传递给许多实体,例如,同时移动相机实体和播放器。

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.