Articles of 实体系统

处理ECS中的持续按键

我目前正处于游戏的计划阶段。 整个事情应该基于实体 – 组件系统(ECS)模式。 所有逻辑都集中在系统内部,即组件只保存数据。 跨系统的通信使用asynchronous事件来执行。 使用这种devise,我无法find简单的移动播放器示例任务的干净解决scheme:当input系统生成按键事件时,我正在寻找一种方法来查询关键状态,因为玩家很可能想要将播放器移动多个帧。 有两种方法可以解决这个问题: 每帧重新触发按键事件 将相应的系统传递给input系统 这两种可能性听起来都不正确,因为它们都需要滥用devise。 有没有更好的方法来解决这个问题?

将c ++模板化函数绑定到lua

我已经开始使用Lua作为我的游戏引擎的脚本语言。 它完美的工作,如input,audio等。但是,我现在试图绑定我的实体组件系统function,大量使用模板。 例如,在c ++中获取一个实体的组件看起来像这样: uint32 entity = 1; Transform &transform = registry.get<Transform>(entity); 并添加一个组件到一个实体: registry.add<Velocity>(entity, 0.0f, 0.0f); 从我可以告诉,Lua无法处理模板函数 – 我将不得不为每个组件绑定一个新的函数,例如getTransformComponent(entity) 。 这显然不是很好,成为最终用户的巨大痛苦。 我查了一下,找不到对我的问题有特别帮助的东西。 我看到一些人提出像getComponent("Transform")但我不明白这是如何在C ++中实现的,因为我的组件是POD ,没有基础的“组件”类?

如何在实体组件系统中构建面向目标的行动计划?

我已经创建了一个使用实体组件系统的JavaScript交互式小说游戏,如此处所述。 我遇到的问题是在开发游戏的AI系统。 理想情况下,我希望使用面向目标的行动计划(GOAP)的人工智能。 不幸的是,这似乎与使用ECS不一致,主要是因为国家模式似乎不适用于这样的entity framework 。 这里有一个简单的例子,可以采取一系列的行动来实现在游戏中接听电话的目标。 目标:响铃时响铃 走到办公桌前 – >坐在椅子上 – >拿起电话 接听电话的路线可能因为其他许多先决条件的存在而不同。 也许这是一个障碍,或者演员不再有椅子坐下。 除此之外,行动者可以在队列中被给予其他优先权。 目前,即使是简单的目标也会引起许多有条件的检查。 我想知道,在这样的游戏中是否可以实现像GOAP这样的东西,我将如何去完成这个? 或者我应该放弃使用GOAP来替代一些AI系统?

是一个适用于这个几何处理系统的实体/组件系统吗?

我正在开发基于组件/实体系统的游戏引擎atm。 我有这个小小的困境。 我有一些简单的几何结构,可以在游戏中下载或创建。 这些结构用于创建在OpenGL和OpenGL ES中使用的模型,然后用于某些冲突处理。 在开发和testing版期间,我对维护物理和显示的数据副本是相当好的。 但是我开始考虑这个引擎的未来,因为我已经花了一年半的时间在这个空间上投入了一些时间。 现在我想复制几个例程到OpenCL内核中,并在我的引擎的服务器端使用GPU的强大function(并准备好支持OpenCL的移动硬件/软件)。 结构是可变的大小和移动或固定的结构可以变形或破碎… ATM的存储是非常低效的。 我想使用几个GLfloat(与OpenCL兼容)的巨型数组,它将根据它们的大小包含我的结构,并且只传递每帧所需的转换。 我的组件然后指向这些数组。 这是正确的做法吗? 如果没有,如何存储结构数据,以便只有在GPU内存需要时才加载并保持组件结构。 我甚至需要一个系统和组件来显示和操作这些结构吗? 注意:这不是一项功课。 让一个小型多人游戏项目尽可能好地运行是一个更有意思的问题。 注:我不能创建一个OpenCL标签,所以如果别人可以,并将其添加到这个问题,将不胜感激。

devise一个基于拼图的益智游戏的实体系统

我正在C#中开发一个基于图块的游戏创建库,并创建一个游戏来testing它的所有function。 这是游戏的截图: 你可能从来没有听说过原始的,但我的游戏是死亡的致命房间(DROD)的克隆,你可以在http://caravelgames.comfind 无论如何,从截图中可以看出,我的游戏(和我的图书馆)都是关于网格上的2D益智游戏,严格的基于回合。 我的图书馆有这样的结构: 实体(Entity) :每一轮都会更新的类,每一个游戏元素都从中inheritance 平铺 :持有实体的类(任何数量的实体) TileManager :包含所有图块的二维数组的类 Field :包含TileManager的类以及用于查询和查找实体的所有方法 为了快速查询和灵活性,我使用接口和inheritance来组织实体。 让我解释为roach实体的代码: public class TDLMonster : TDEntity, IHasTarget, IDrawn, IHasDirection, ISolid, IHitByWeapon, IHitByMonster { … } TDLMonster类从TDEntityinheritance(从实体inheritance)。 它也使用接口来标记元素的某些属性。 public interface IHitByWeapon : IEntity { void HitBySword(IWeapon mWeapon); } 这是IHitByWeapon接口。 每回合之后,武器检查他们的瓦片上是否有任何IHitByWeapon的实例。 如果有,请致电HitBySword。 这是这样的代码: public virtual void CheckHits() { List<Entity> hitEntities = Field.GetEntities(X, Y, […]

我如何去创建“Watcher”组件?

上个周末,我花了几个小时在JavaScript中编写一个基本的实体组件模型。 我主要参考了Ash Actionscript游戏引擎。 我成功地研究了系统,组件,节点和实体如何链接起来,但是有一点我不能解决,那就是如何实现“观察者”来检查组件的实体,为它们创建节点,将这些节点添加到各种系统自动,并监视实体组件的任何变化。 我对Ash的工作方式感到有点困惑,所有关于这个主题的post和教程似乎都放弃了这部分实现的细节。 目前,我目前有以下几点: 实体,这是分配的组件。 引擎,跟踪系统和实体。 节点,其中包含我们希望系统修改(我目前正在创建这些,手动,并将其添加到系统)的实体中组件的引用。 组件,其中包含要由系统修改的数据。 系统,在节点上运行,从而改变实体中的数据。 我还有其他各种课程,致力于保存各种对象的列表。 我如何去创建“Watcher”组件?

我如何处理实体系统中的刀枪不入?

我目前有一个实体组件系统与消息。 消息被传送给每个用户,但是每个用户都得到他们自己的副本,这基本上意味着改变消息不会影响任何其他用户。 虽然这工作现在罚款,我想知道我将如何添加一个无懈可击的状态。 我有一个解决战斗的战斗系统。 它需要一个战斗事件(意图攻击的东西),并发出一个解决的战斗事件。 这个事件包含谁攻击谁和谁受到什么样的伤害的信息。 它也有一个bool,它给出了攻击之后这个实体是否还活着的状态。 它也控制着惠普,并删除实体,如果它被杀害。 我没有打破这个系统的问题。 计算伤害的系统,施加伤害的系统以及杀死实体的系统。 但我在哪里添加我的无敌? 如果我只是把它作为一个组成部分,那么它必须由应用损害的系统来处理。 如果我想稍后添加其他内容呢? 我必须建立和完善损害系统,它必须处理所有的小问题和错综复杂的问题。 如果我想添加一个经受无敌攻击的攻击呢? 显然,这是一个指数级的噩梦,这正是我希望通过ECS避免的。 我应该如何处理刀枪不入?

在实体组件系统中获取特定组件

我有组件类: class Component { public: Component(); … }; 那么我的各种组件派生自基础Component类 class VelocityCom : public Component { public: VelocityCom(); … }; 然后是一个拥有这些组件的实体类,并且能够返回一个特定的组件进行操作 class Entity { public: Entity(); std::unique_ptr<Component> getComponent(…); private: std::vector<Component> components; }; 这种方法存在的问题在于获取特定组件的行为。 假设我想获得一个指向velocity组件的指针。 我不能只有whateverEntity.getComponent(Types::Velocity); 因为该方法返回一个Component而不是VelocityCom 。 我想到了将Component指针投射到VelocityCom指针,但似乎很多人不喜欢downcasting的想法。 所以我的问题是什么是在实体组件系统中获取特定组件的好方法? 在这种情况下是否可以向下转换,或者我应该把执行改变到我不需要的地方?

实体组件系统中的dynamic事件

我的游戏广泛使用了libGDX的实体组件系统Ashley,而我的游戏世界(包括所有级别和区域)是用Tiled创建的。 在Tiled中,我有一个对象层,其中添加了所有的实体(如矩形,虽然形状不重要)。 每个对象属性都链接到一个包含序列化组件的YAML文件,这些组件在添加实体时被反序列化。 这个系统运行良好,我想用一个类似的方法来处理所有types的地图事件,虽然我不知道这样做的方法。 我想创建dynamic事件: 有一个或多个原因 为每个原因有一个或多个效果 原因是玩家与开关互动,而效果是开门。 一个或多个原因可能是,例如,玩家必须具有特定项目并且与交换机进行交互。

使用newthread的多个lua脚本

我试图钩lua脚本到我的实体,其中几个相同types的实体要使用相同脚本的单独的实例。 问题是,当我运行两个或多个脚本并使用任何C-apifunction时,一段时间后我会遇到访问冲突。 我猜一些堆栈腐败发生,但我不知道。 应用程序是单线程的,但为每个实体使用lua_newthread,然后在每个新线程上使用lua_resume来运行脚本。 代码看起来像这样。 脚本1 function Update(dt, owner) print("Script 1") pos = GetPosition(owner) end 脚本2 function Update(dt, owner) print("Script 2") end 为getPosition() static int GetPosition(lua_State* L) { Core::Entity entity = lua_tonumber(L, 1); Core::TransformationComponent* tc = WGETC<Core::TransformationComponent>(entity); lua_newtable(L); for (int i = 0; i < 2; i++) { lua_pushnumber(L, tc->position[i]); lua_rawseti(L, -2, i); } return […]