Questions tagged «component-based»

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

5
如何在基于组件的游戏中正确处理碰撞?
在围绕组件设计的游戏中,尝试绕过正确处理碰撞的方法。 我看到许多示例PhysicsComponent在实体的组件列表中添加了某种示例,但实际的实现使我感到困惑。 为了PhysicsComponent使它起作用,需要访问周围的环境。这对我来说没有直觉。组件不应该不仅意识到其容器(实体),还没有意识到其容器的容器(世界)吗? 对我来说,听起来好像关卡或场景应该维护这些实体的列表,并且每次游戏更新都会遍历这些实体以确定哪个碰撞。 我的问题是,首先,这是否是好的设计,其次,如何确定哪些实体会发生冲突。我想实体实体可以实现一个空的IRigidBody接口,以便该级别可以确定列表中的哪些实体支持冲突。但这会破坏组件设计吗? 相反,它们应该包含一个空的RigidBody成分吗?实际上,这可能会更好,因为它可能并不总是空的,而且这种方法更适合未来。唯一的问题是复杂性。场景不仅必须遍历每个实体,还必须遍历每个实体的组件,以确定它是否具有此RigidBody组件。 第三,当它们确实发生碰撞时,应该以某种方式告知两个实体,我也不确定如何做到这一点。 假设两个实体都包含一个HealthComponent,并且当它们碰撞时,两个实体的健康状况都会降低一些任意值5。我想当场景中检测到两个实体之间发生碰撞时,要负责处理此问题? 但是,现场是否要承担太多责任?当场景负责实体不应该访问的许多事物时,我可以看到这种情况可能会变得一发不可收拾并且变得笨拙。 编辑:问题已更新,具有更多详细信息。

4
如何在不破坏每个实体单一类型的一个组件的情况下,为每个实体使用多个网格?
我们只是从基于层次的游戏引擎切换到基于组件的游戏引擎。我的问题是,当我加载具有网格层次结构的模型时,我的理解是,基于组件的系统中的实体不能具有相同类型的多个组件,但是每个组件都需要一个“ meshComponent”在模型中进行网格划分。那么我该如何解决这个问题。 他们在此站点上实现了基于组件的游戏引擎:http : //cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

2
在基于组件的实体系统中处理脚本化和“本机”组件
我目前正在尝试实现一个基于组件的实体系统,该实体基本上只是一个ID和一些将一组组件捆绑在一起以形成游戏对象的辅助方法。其中的一些目标包括: 组件仅包含状态(例如位置,健康状况,弹药计数)=>逻辑进入“系统”,该系统处理这些组件及其状态(例如PhysicsSystem,RenderSystem等) 我想用纯C#和脚本(Lua)实现组件和系统。基本上,我希望能够直接在Lua中定义全新的组件和系统,而不必重新编译C#源代码。 现在,我正在寻找有关如何高效且一致地处理此问题的想法,因此,例如,无需使用其他语法来访问C#组件或Lua组件。 我当前的方法是使用常规的公共属性实现C#组件,这些属性可能装饰有一些属性,这些属性可以告诉编辑器默认值和内容。然后,我将得到一个C#类“ ScriptComponent”,该类仅在内部包装Lua表,该表由脚本创建并保存该特定组件类型的所有状态。我真的不希望从C#端访问该状态,因为我在编译时不知道可以使用哪些ScriptComponents和哪些属性。尽管如此,编辑器仍需要访问它,但是像下面这样的简单界面就足够了: public ScriptComponent : IComponent { public T GetProperty<T>(string propertyName) {..} public void SetProperty<T>(string propertyName, T value) {..} } 这将简单地访问Lua表并从Lua设置和检索那些属性,并且也可以轻松地将其包含在纯C#组件中(但随后可以通过反射或其他方式使用常规C#属性)。这只能在编辑器中使用,不能用常规的游戏代码使用,因此性能在这里并不重要。这将有必要生成或手写一些组件描述,以记录某些组件类型实际提供的属性,但这不是一个大问题,并且可以实现足够的自动化。 但是,如何从Lua端访问组件?如果我调用类似的东西,getComponentsFromEntity(ENTITY_ID)我可能只会获得一堆本地C#组件(包括“ ScriptComponent”)作为用户数据。从包装的Lua表访问值将导致我调用该GetProperty<T>(..)方法,而不是像其他C#组件那样直接访问属性。 也许编写一个getComponentsFromEntity()只能从Lua调用的特殊方法,该方法会将所有本机C#组件作为用户数据返回,但“ ScriptComponent”除外,它将返回包装后的表。但是会有其他与组件相关的方法,我真的不想复制所有这些方法,无论是从C#代码还是从Lua脚本调用。 最终目标将是处理所有类型的组件相同,而在本机组件和Lua组件之间(尤其是从Lua方面)不区分特殊情况的语法。例如,我希望能够编写如下的Lua脚本: entity = getEntity(1); nativeComponent = getComponent(entity, "SomeNativeComponent") scriptComponent = getComponent(entity, "SomeScriptComponent") nativeComponent.NativeProperty = 5 scriptComponent.ScriptedProperty = 3 该脚本不必关心它实际上获得了哪种组件,我想使用与C#端相同的方法来检索,添加或删除组件。 也许有一些将脚本与实体系统集成在一起的示例实现?

5
为什么将实体配置放在脚本之外?
我见过很多在脚本文件中定义实体组件的游戏,但是当它们配置每个实体并指定其具有的组件时,它们会使用其他文件格式(例如XML)。他们为什么这样做? 我主要是想看看其他人对此的依据是什么。我还在脚本之外配置了我的实体(尽管我选择了JSON而不是XML)。我这样做的原因是使我更容易实现保存游戏,还因为我认为这种配置可以更好地组织为XML或JSON之类的东西。 // @ 克里斯托弗·拉森的答案: 太长了,无法发表评论 我担心您可能偏离了问题的主题。您所描述的问题与基于层次的实体更相关;在我提到的问题中,我提到我在谈论基于组件的实体。 这是我想问的一个例子。以下是配置实体的两种替代方法:通过脚本和通过外部JSON文件。我的问题是,为什么有那么多人喜欢在脚本之外配置实体? 基础实体类: class Entity: def __init__(self, name): pass def addComponent(self, comp): pass 脚本方法: orc = Entity('Orc') orc.addComponent(PositionComponent(3.4, 7.9)) JSON方法: { "name" : "Orc", "components": { "PositionComponent": { "x" : 3.4, "y" : 7.9 } } } 我已经说明了使用这种方法的原因,包括技术上和组织上的原因。我想知道为什么这么多其他人(根据我所看到的)使用它。

4
单人游戏引擎应如何有力地拒绝无效数据?
在单人游戏中,当尝试使用外部脚本中指定的组件构建实体时,您认为在其中一个组件格式不正确时会发生什么更可取: 引擎是否应该跳过该组件,而仅使用编写良好的组件让实体生活在游戏世界中? 还是如果其中一个组件的格式不正确,它是否根本不应该将该实体添加到整个世界? 请注意,我不是在谈论记录错误-不用说-只是关于实体应该发生什么。

1
在游戏子系统中注册游戏对象组件?(基于组件的游戏对象设计)
我正在创建一个基于组件的游戏对象系统。一些技巧: GameObject只是的清单Components。 有GameSubsystems。例如,渲染,物理等。每个都GameSubsystem包含一些指向的指针Components。GameSubsystem是一个非常强大且灵活的抽象:它代表游戏世界的任何部分(或方面)。 有在登记的机构的需要Components在GameSubsystems(当GameObject被创建和组成)。有4种方法: 1:责任链模式。每个人都Component被提供给每个人GameSubsystem。GameSubsystem决定Components要注册的内容(以及如何组织)。例如,GameSubsystemRender可以注册可渲染组件。 亲 Components对如何使用它们一无所知。低耦合。答:我们可以添加新的GameSubsystem。例如,让我们添加GameSubsystemTitles来注册所有ComponentTitle,并确保每个标题都是唯一的,并提供按标题查询对象的接口。当然,在这种情况下,ComponentTitle不应该被重写或继承。B.我们可以重组现有的GameSubsystems。例如,可以将GameSubsystemAudio,GameSubsystemRender,GameSubsystemParticleEmmiter合并到GameSubsystemSpatial中(以将所有音频,发射器,渲染Components置于相同的层次结构中并使用父相对转换)。 骗子 每次检查。效率很低。 骗子 Subsystems知道Components。 2:每个Subsystem搜索Components特定类型。 亲 性能比更好Approach 1。 骗子 Subsystems仍然知道Components。 3:在中Component注册自己GameSubsystem(s)。我们在编译时知道有一个GameSubsystemRenderer,所以让ComponentImageRender调用类似GameSubsystemRenderer :: register(ComponentRenderBase *)之类的东西。 亲 性能。没有像中那样不必要的检查Approach 1。 骗子 Components与...严重耦合GameSubsystems。 4:调解员模式。GameState(包含GameSubsystems)可以实现registerComponent(Component *)。 亲 Components和GameSubystems什么都不知道对方。 骗子 在C ++中,它看起来像丑陋且缓慢的typeid开关。 问题: 哪种方法更好,并且主要用于基于组件的设计?什么做法说?关于实施的任何建议Approach 4? 谢谢。

2
如何在基于实体/组件的系统中构造游戏状态
我在做设计与实体分量范例,使用系统组件之间的通信,说明游戏在这里。在开发过程中,我已经达到需要添加游戏状态(例如暂停,播放,关卡开始,回合开始,游戏结束等)的地步,但是我不确定如何在我的框架中进行操作。我看这对游戏状态的代码示例,每个人都似乎是参考,但我不认为它与我的框架适合。似乎每个状态都处理自己的绘图和更新。我的框架有一个SystemManager,可以处理使用系统进行的所有更新。例如,这是我的RenderingSystem类: public class RenderingSystem extends GameSystem { private GameView gameView_; /** * Constructor * Creates a new RenderingSystem. * @param gameManager The game manager. Used to get the game components. */ public RenderingSystem(GameManager gameManager) { super(gameManager); } /** * Method: registerGameView * Registers gameView into the RenderingSystem. * @param gameView …

2
由于libGDX中不推荐使用Table.drawDebug,因此应该使用什么呢?
我正在按照“学习LibGDX游戏开发”一书来制作一个简单的游戏。我在菜单创建部分中,在其中创建一个舞台并使用调试边框对其进行渲染。 这本书说要使用,Table.drawDebug(stage)但是这个静态方法似乎已经从框架Table类中完全删除了。 我正在进口com.badlogic.gdx.scenes.scene2d.ui.Table; 下面是我的代码: @Override public void render(float deltaTime) { Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); if (debugEnabled) { debugRebuildStage -= deltaTime; if (debugRebuildStage <= 0) { debugRebuildStage = DEBUG_REBUILD_INTERVAL; rebuildStage(); } } stage.act(deltaTime); stage.draw(); Table.drawDebug(stage); } 最后一行,Table.drawDebug(stage);有编译错误"The method drawDebug(ShapeRenderer) in the type Table is not applicable for the arguments (Stage)" …

1
一个人如何在实体组件系统中存储全局上下文数据?
我的问题是这样的: 一个将如何存储全局上下文数据,即。实体组件系统中的世界数据信息,当前世界时间等? 我正在考虑使用C ++构建矮人要塞风格的开放式世界模拟游戏。我只是出于娱乐目的而建立了一个实体组件样式的游戏引擎,而我目前正在试图弄清楚如何在所有想要的功能中工作。除了标准的游戏玩法(渲染,物理,特定于实体的组件数据等)之外,我还希望获得一些所有相关系统都可以访问的全局上下文数据(即世界数据,例如当前的年份) ,全球变暖是否正在发生,与模拟世界有关的任何事物)。我最初曾想过要制作一个“世界”组件,但是如果许多不同的系统需要访问这个逻辑上的“全局”数据,这似乎毫无意义且困难。 拥有“世界”组件是否有意义,还是应该以其他方式存储此数据? 我还考虑过将这些数据简单地全局化,从而可以访问任何想要使用它的系统。这似乎总体上违反了实体组件原则,并且由于其他原因可能有些混乱,但是我认为这可能确实有效。 我想到的另一件事是将相关的世界上下文数据直接直接嵌入系统本身。例如,如果我有一个AgeSystem“老化”的具有getsWeakerAsTimePasses组件之类的所有实体,那么也许该系统可以直接将世界的相关时间数据存储为成员数据,以用于计算时间的流逝以及需要多少时间。年龄和弱化人们等。这是我最不喜欢的第三种选择,但是在头脑风暴中发生了一些事情。 有人可以建议吗?

3
如何在实体组件系统中避免“斑点系统”?
目前,我面临以下问题: 我正在尝试通过使用实体组件系统(ECS)来编写pong克隆。我自己写了“框架”。因此,有一个类管理具有所有组件的实体。然后是组件类本身。最后是我的系统,它仅获取具有系统所需组件的所有实体。 因此,例如,我的运动系统会查找具有位置分量和运动分量的所有实体。位置分量仅保持位置,而运动分量则保持速度。 但是实际的问题是我的碰撞系统。这个类就像一个逻辑blob。我在这堂课上有很多特殊情况。 例如:我的桨可能会与边框碰撞。如果发生这种情况,其速度将设置为零。我的球也可能与边界碰撞。但是在这种情况下,它的速度仅反映在边界的法线上,因此可以反映出来。为此,我给球添加了一个额外的物理组件,它告诉:“嘿,这件事并没有停止,它反映了这一点。” 因此,实际上,物理组件没有实际数据。它是一个空类,仅用于告诉系统对象是否反射或停止。 然后是这样:当球与球拍或边框碰撞时,我想渲染一些粒子。因此,我认为球必须具有另一个组件,该组件告诉碰撞系统在碰撞时创建粒子。 然后,我想要一个可以与桨碰撞但不能与边界碰撞的力量提升器。如果发生这种情况,通电将消失。因此,我需要更多的情况和组件(以告诉系统某些实体只能与某些其他实体发生碰撞,即使某些其他实体确实可以发生碰撞,机器人也不能与所有实体发生碰撞,此外,碰撞系统还必须对这些实体施加动力桨等,等等。)。 我看到实体组件系统是一件好事,因为它很灵活,并且继承没有问题。但是我现在完全陷入困境。 我觉得太复杂了吗?我该如何应对? 当然,我必须创建实际上负责“碰撞后”的系统,因此碰撞系统只会告诉“是的,我们在最后一帧发生碰撞”,然后有许多“碰撞后”系统所有这些都需要不同的(组合)组件,然后更改组件。例如,将有一个运动后碰撞系统,该系统停止发生碰撞时必须停止的东西。然后是一个反映事物等的物理后碰撞系统。 但这似乎也不适合我,因为例如: 我的运动碰撞后系统将需要具有位置分量,运动分量和碰撞分量的实体。然后,它将实体的速度设置为零。 物理后碰撞系统将需要具有位置成分,运动成分,碰撞成分和物理成分的实体。然后它将反映速度矢量。 问题很明显:运动后碰撞需要实体,这些实体是物理后碰撞系统中实体的子集。因此,两个碰撞后系统将对相同的数据进行操作,其结果是:尽管实体具有物理成分,但碰撞后速度为零。 这些问题一般如何在实体组件系统中解决?这些问题甚至很常见吗?如果是,那么应该怎么做以及如何做呢?

2
何时/何地更新组件
我不是使用通常的继承重型游戏引擎,而是使用基于组件的方法。但是,我很难说明让组件在哪里工作。 假设我有一个简单的实体,其中包含一个组件列表。当然,实体不知道这些组件是什么。可能存在一个使实体在屏幕上处于某个位置的组件,可能还有一个组件在屏幕上绘制该实体。 为了使这些组件正常工作,它们必须在每一帧进行更新,最简单的方法是遍历场景树,然后为每个实体更新每个组件。但是某些组件可能需要更多管理。例如,使实体可碰撞的组件必须由可以监视所有可碰撞组件的组件来管理。使实体成为可绘制实体的组件需要某人监督所有其他可绘制组件以找出绘制顺序,等等。 所以我的问题是,在哪里更新组件,将它们带给管理者的干净方法是什么? 我已经考虑过为每种组件类型使用单例管理器对象,但是它具有使用单例的通常缺点,一种缓解此问题的方法是使用依赖项注入,但这听起来像是针对此问题的过大杀伤力。我还可以遍历场景树,然后使用某种观察者模式将不同的组件收集到列表中,但是这样做似乎浪费每一帧。

3
如何在基于组件的游戏中更新实体状态和动画?
我正在尝试设计一种基于组件的实体系统,以供学习(以及以后在某些游戏中使用),并且在更新实体状态时遇到了一些麻烦。 我不想在组件内部使用update()方法来防止组件之间的依赖关系。 我目前要记住的是,组件保存数据,而系统更新组件。 因此,如果我有一个简单的2D游戏,其中包含一些具有“变形”,“运动”,“状态”,“动画”和“渲染”组件的实体(例如玩家,敌人1,敌人2),我认为我应该拥有: 一个MovementSystem,用于移动所有Movement组件并更新State组件 还有一个RenderSystem,用于为每个状态更新Animation组件(animation组件应具有一个动画(即一组帧/纹理),并对其进行更新意味着选择与当前状态相对应的动画(例如,jumping,moving_left等),以及更新框架索引)。然后,RenderSystem使用与每个实体的Animation的当前帧相对应的纹理更新Render组件,并将所有内容呈现在屏幕上。 我已经看到了一些像Artemis框架的实现,但是我不知道如何解决这种情况: 假设我的游戏包含以下实体。每个实体都有一组状态和每个状态一个动画: 播放器:“ idle”,“ moving_right”,“ jumping” 敌人1:“上移”,“下移” 敌人2:“向左移动”,“向右移动” 为了更新每个实体的当前状态,最常用的方法是什么?我唯一能想到的就是为每个实体组分别具有单独的系统以及单独的State和Animation组件,因此我将拥有PlayerState,PlayerAnimation,Enemy1State,Enemy1Animation ... PlayerMovementSystem,PlayerRenderingSystem ...但我认为这很不好解决方案并打破了拥有基于组件的系统的目的。 如您所见,我在这里很迷路,因此非常感谢您的帮助。 编辑:我认为使这项工作如我所愿的解决方案是: 使statecomponent和animationcomponent具有足够的通用性,可用于所有实体。它们包含的数据将成为修改诸如播放动画或可用状态之类的修改器。–字节56 现在,我试图弄清楚如何设计这两个通用组件,以便我可以重用它们。可以为每个状态(例如,步行,跑步...)设置UID并将动画存储在地图中并由该标识符作为键的AnimationComponent中吗?

3
组件实体系统-更新和呼叫订单
为了使组件能够更新每一帧(并使此功能不包含在不需要的组件中),我想到了制作一个UpdateComponent组件的想法。诸如MovableComponent(保持速度)的其他组件将从IUpdatable抽象类继承。这迫使MovableComponent实现一个Update(gametime dt)方法,而另一个RegisterWithUpdater()实现提供UpdateComponent了指向的指针MovableComponent。许多组件可以执行此操作,然后UpdateComponent可以调用其所有Update(gametime dt)方法,而不必关心它们是谁或什么。 我的问题是: 这看起来像是正常的东西还是任何人使用的东西?我在这个问题上找不到任何东西。 我该如何维护物理等组件的顺序,然后更改位置?这有必要吗? 还有什么其他方法可以确保应处理的每一帧实际上都得到处理? 编辑 我想我将考虑如何为实体管理器提供可更新的类型列表。然后,该类型的所有组件都可以更新而不是针对每个实体进行管理(无论如何,它们只是我系统中的索引)。 仍然。我的问题对我仍然有效。我不知道这是否是理性/正常的,还是其他人倾向于这样做。 另外,失眠症患者也很棒! /编辑 为前面的示例精简代码: class IUpdatable { public: virtual void Update(float dt) = 0; protected: virtual void RegisterAsUpdatable() = 0; }; class Component { ... }; class MovableComponent: public Component, public IUpdatable { public: ... virtual void Update(float dt); private: ... …

3
创建实体作为聚合
我最近询问了如何将实体与其行为分开以及与本文相关的主要答案:http : //cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ 这里讨论的最终概念是:作为纯聚集体的对象。 我想知道如何使用C#将游戏实体创建为纯聚合。我还不太了解如何运行的概念。(也许实体是实现特定接口或基本类型的对象的数组?) 我当前的想法仍然涉及为每种实体类型都有一个具体的类,然后实现相关的接口(IMoveable,ICollectable,ISpeakable等)。 我如何才能完全将实体创建为聚合,而又没有该实体的任何具体类型?

2
如何通过缓存友好的组件存储安全地支持组件到对象的通信?
我正在制作一个使用基于组件的游戏对象的游戏,但是我很难为每个组件实现一种与其游戏对象进行通信的方式。我将不解释所有内容,而是解释相关示例代码的每个部分: class GameObjectManager { public: //Updates all the game objects void update(Time dt); //Sends a message to all game objects void sendMessage(Message m); private: //Vector of all the game objects std::vector<GameObject> gameObjects; //vectors of the different types of components std::vector<InputComponent> input; std::vector<PhysicsComponent> ai; ... std::vector<RenderComponent> render; } 在GameObjectManager拥有所有的游戏对象及其组件。它还负责更新游戏对象。它通过按特定顺序更新分量向量来实现。我使用向量而不是数组,因此可以同时存在的游戏对象数量实际上没有限制。 class GameObject …

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.