Articles of 实体系统

基于组件的实体系统中的Tilemap冲突

我正在尝试在基于组件的实体系统中为一个tilemap设置一个碰撞系统,但在解决这个问题的时候遇到了麻烦。 目前我有以下的方法:我的地图包含一个只保存数组的Tilemap_Component,一个保存Tileset图像的Tilemap_Render_Component,以及一个Tilemap_Collision_Component,它保存瓦片值作为墙壁处理的信息。 为了使一个实体与tilemap碰撞,它现在需要下列组件:保存X / Y速度的Movement_Component,保存X / Y位置的Position_Component和保存信息的Tilemap_Collider_Component,如果对象只与墙壁碰撞,或者与地图中的一些其他对象一起使用。 现在我的问题是以下几点:确定如何处理与tilemap碰撞的对象是非常困难的。 如果将速度设置为零,则可能在墙上产生毛刺,因为运动和input是在碰撞之外的其他系统中处理的。 如果我只是改变对象的位置,就会出现两个问题:一是对象开始闪烁,因为它已经移动了一下。 另一个是,我将不得不知道与墙壁碰撞的物体有多大。 现在我可以说Render_Component对于可以与tilemap碰撞的对象是必需的,然后使用对象的Render_Component中的图像信息和tilemap的Tilemap_Render_Component来计算碰撞,但是我认为这有点违背了意图基于组件的系统。 你会有什么建议? 我怎么能处理这个问题? 或者,你们中的任何一个人是否面临这样的问题? 你是怎么解决的?

在实体系统devise中把通用系统function放在哪里?

我正在基于Adam Martin的devise和Ray Wenderlich的Objective-C实现来开发一个实体系统devise。 我正在AI系统上使用状态机,每个状态都有一个System。 但是,这些系统中的很多都具有很多function,例如: -(NSArray*)findEnemiesOfEntity:(Entity*)entity withinRange:(float)range { // Get all entities with a Team component // Narrow down entities to those on opposing team // For those that have a Position component: // Get their position // If their position is within range: // Add to array of return values // Return array of […]

ECS如何在系统中访问多个组件(不一样)?

我正在从http://entity-systems.wikidot.com/rdbms-with-code-in-systems#java用C ++实现一个基本的实体组件系统,但是我不太了解如何做多个组件不是相同的组件,我不认为有必要在系统中有2个相同的组件)。 在inheritance的系统中,例如MovementSystem,我希望它能够对所有具有位置分量和速度分量的实体起作用。 但是,在我的代码中,我会这样做 std::vector<Component *> positionComps = entityManager->GetAllComponentsOfType(POSITION_COMPONENT); std::vector<Component *>::iterator it = components.begin(); for (; it != positionComps; it++) { PositionComponent *pos = dynamic_cast<PositionComponent *>(it); pos->x += velo->x; } 我不知道如何在那里获得速度分量,因为它正在循环通过位置分量。 我可以在该循环中获得types为velocity的所有组件,并且有一个嵌套的循环,但是这会对性能造成影响。 另外,你怎么知道哪个组件与哪个? GetAllEntitiesPossessingComponent函数返回一个整数列表,所以我可以稍后获取实体的特定组件,并检查实体是否具有这两个组件。 另外,如果返回的组件是NULL,那么在我做任何事情之前,如果它是NULL,我将不得不检查系统。 但是,这一切似乎都不正确。 我可以将PositionComponent和VelocityComponent合并成一个,然后在系统上执行,但是这对我将来的组件没有帮助。

从对象方法中销毁对象

我的游戏使用一个实体经理和实体来表示一切,包括玩家,敌人,物品,……游戏中的一切。 在我的引擎中,每个实体都有责任自我更新。 有时一个实体发现它已经过期了,因此需要从实体管理器中删除。 我的问题是:有一个对象删除自己是否安全? 我将说明我的意思。 void EntityManager::remove_entity(Entity* entity) { m_entities.erase(std::remove_if( //… } void Entity::update() { if (has_expired) m_manager.remove_entity(this); // <- safe? } 我不能用这个来具体地certificate一个bug,但是它的外观和感觉应该至less是未定义的行为。 那可以吗? 如果不是的话,处理这种情况的常见做法是什么?

在我的ECS中添加新的组件和系统需要大量的样板代码

我正在为我一直在研究的项目编写一个实体组件系统。 它目前处于工作状态,总的来说我很满意,但是我注意到向它添加新的组件和系统需要相当多的样板代码。 我一直在研究ECS,而且我不完全确定这是否正常。 我读过的东西中没有一个提到添加新组件或系统通常需要多less样板文件。 这是我deviseECS的方法。 实体类携带一个id和一个智能指针映射到它的组件。 实体在YAML中定义,工厂类分析YAML并创建实体需要的所有组件。 实体存储在主引擎类中。 系统拥有一个节点向量,每个节点只包含特定系统所需的组件。 每更新一次,系统循环遍历节点,删除具有无效指针的指针,并用有效指针更新指针。 到目前为止,组件创建的样板还不错。 每个新组件还必须附带一个返回自身实例的函数,而且工厂需要更新函数指针映射以包含所述函数。 用于制造新系统的锅炉更差。 每个节点中的指针都是硬编码的。 如果一个节点需要持有很多指向不同组件的指针,事情会很快变得混乱。 Node构造函数列出每个组件的指针。 注册实体的function必须检查实体是否包含任何组件。 更新函数必须检查节点中每个指针的有效性。 显然,所有这些都需要完成,但是对节点组件的更改需要在4个不同的地方更新系统,创建一个新组件需要更新工厂类中的东西。 如果大量的样板代码是与实体组件系统一起工作的现实,那么我没有问题,因为它有很多好处。 但是,我不知道是否有更好的方法来处理这些事情。

游戏服务器请求处理

编辑:我忘了提及,在这个实现中,E代表实体,这只是一个ID,C =>组件作为数据types和S系统应该实现逻辑 目前我正在做一个小型的爱好项目,这是一个多客户端/服务器架构的多人纸牌游戏。 我正在使用一个框架的networking部分触发消息事件的服务对象是这样的: class AuthRequestMessage : public fqpnet::IMessage { public: //methods for serialization inline const std::string& getLoginId() const { return loginId_; } inline const std::string& getPassword() const { return loginId_; } private: std::string loginId_; std::string password_; }; //Handles authentication class GatewayService : public fqpnet::Service { public: //registers handlers GatewayService() private: void onAuthRequestMessage(const AuthRequestMessage* msg, […]

在devise组件时需要一些建议

所以在阅读了一下组件之后,我想制作一个非常简单的使用组件和系统的太空射击游戏。 不过,我对每个组件应该有多less范围有点困惑。 例如,假设游戏中有飞来飞去的小行星,如果你击中它们,就会受到伤害。 他们也有健康。 小行星实体然后可能包含这些组件: SpriteComponent(Texture2D纹理) HealthComponent(int amount) CollidableComponent(bool刚性) MovementComponent(int x,int y) RotationComponent(int度) 现在让我们说我们有一个RenderSystem。 它的Update()方法需要SpriteComponent,MovementComponent和RotationComponent来绘制一个实体。 这一切都很好,但是什么时候会有MovementComponent而不是RotationComponent? 我们不能只有一个包含x,y和旋转的TransformComponent吗? 将这些组件devise成只是一种数据types的容器,感觉有点奇怪。 但是,你在哪里画线? 所有的精灵也有位置和旋转量,所以SpriteComponent应该包含TransformComponent,还是应该将TransformComponent的成员移动到SpriteComponent? 但问题是如果你想要一个位置和旋转的实体,但没有精灵。 然后你必须给它一个空的纹理(不一定是一个坏的解决scheme),或者维护TransformComponent,并让SpriteComponent也包含它(或者只是传递两者)。 有很多决定要做,而且当我开始面向对象编程时,我真的感觉很相似。 “什么应该是对象?它的方法应该是什么?这应该是公共的还是私人的? 很明显,我已经知道了所有这些,但是这个新的基于组件的范例现在给了我同样的问题。 有没有人有任何建议或标准的组件为基础的devise通常使用的组件,以及如何通常会这样的事情?

关于实施基于组件的实体系统的细节的问题

我开始阅读关于基于组件的实体,整体而言这似乎是一个好主意,但是其中很多似乎跳过了很多细节,并没有给出很多实例,所以有些东西对我来说并没有什么意义。 请注意,我也主要讨论了组件仅保存数据的体系结构,并作为触发系统为该实体运行的键,但这仍然主要适用于每个组件具有由实体调用的更新方法。 何时去思考,是否有许多实体有共同的东西(比如有碰撞和物理的敌人),加上只有这种实体才具有的行为。 我是否需要创建许多只适用于某种实体的系统,而不是通用的/可重用的? 组件应该如何相互影响? 我听说过使用消息队列,但似乎这将是缓慢的,再加上我将如何阻止排队消息,永远不会被读取? 或者只是设置组件中的字段(由其他系统检查)认为是好的? 处理碰撞检测的最佳方法是什么? 检查冲突并发送事件/将碰撞对象存储在组件中的系统? 只是给世界/实体经理一个方法(可以被不同的系统自由使用)来find具有某个组件的碰撞实体是一个好主意? 还是有另一种方式? 如何处理基于事件的animation变化? 如果我有一个组件告诉animation组件切换到某个animation,是不是这样,使组件不能用于不同的animation? 在2D中,如何处理绘图顺序? 特别是如果有多种绘图系统? 使用OOP,您可以将对象的引用存储在另一个对象中,并调用其中的方法。 如果考虑到实体不保证具有某些组件,那么对于一个实体/组件系统来说,这将如何完成呢? 那么这些问题是如何解决的呢? 还是我想这完全是错误的方式?

具有特定要求的devise问题(需要逻辑相关性)

我开始为小型3D环境编写一些代码。 这个星期,我想从我的实体开始,当我再次考虑这个问题时,我偶然发现了一些未满足的要求。 我的devise在游戏循环方面工作正常,但我错过了不同实体之间的逻辑关系。 为了展示我的意思:我的实体可以通过一个共同的接口(我的基类)进行交互,但是他们缺乏对特定环境作出反应的能力,例如想象你有一些不同动物的模拟。 有些是食肉动物(pretator)和一些食草动物(猎物)。 当我想到我的devise,我不知何故错过了包括捕捉实体的环境的能力。 我的猎物无法find他们附近的食肉动物(“我是否有被吃掉的危险?我应该逃跑还是我安全?”),掠食者也不能追捕猎物。 所以我正在寻找一种能够通过单一界面(游戏端)管理所有实体的devise,并允许有关环境的信息(实体端)。 除此之外,还有更多的条件: 线程安全 可扩展通过DLL(我使用C ++) 有效性 注意:我的实体不需要在运行时改变属性(如在ECS中),我希望注入的实体(通过DLL)与原来的正常工作(例如,如果有人通过DLL添加狮子,任何猎物应该正确对附近的狮子反应,因为它们是一种捕食者)。

实体系统和呈现types

我想在我的游戏中实现实体系统,我对实体系统和渲染有一些疑问。 目前,我的渲染器有两种types的元素: 目前的devise 网格:使用材质,几何和可变形的默认可渲染 Sprite:一种类似于“flip”和“setRect”方法以及rect成员的方法(带有强制几何体,四元组) 这个对象inheritance了“Spacial”类。 问题: 我如何在一个实体系统中处理这两种types? 我正在考虑使用“MeshComponent”和“SpriteComponent”,但是如果我这样做,一个实体可以有一个Mesh和一个Sprite在同一个types,这看起来很愚蠢,对吧? 我认为这个想法有一个父“渲染”组件:“RenderableComponent”为“MeshComponent”和“SpriteComponent”,但它将很难处理在游戏中“投”(例如:我是否需要问entity-> getComponent或SpineComponent,…) 非常感谢您的阅读! 我的实体系统是这样工作的: ————————————————————————— Entity* entity = world->createEntity(); MeshComponent* mesh = entity->addComponent<MeshComponent>(material); mesh->loadFromFile("monkey.obj"); PhysicComponent* physic = entity->addComponent<PhysicComponent>(); physic->setMass(5.4f); physic->setVelocity( 0.5f, 2.f ); ————————————————————————— class RenderingSystem { private: Scene scene; public: void onEntityAdded( Entity* entity ) { scene.addMesh( entity->getComponent<MeshComponent>() ); } } class PhysicSystem { private: […]