- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在游戏开发中,有一个实体系统的概念,旨在通过获得灵活的架构来简化游戏循环。有关详细信息,请参阅以下链接:
http://www.richardlord.net/blog/what-is-an-entity-framework
http://shaun.boyblack.co.za/blog/2012/08/04/games-and-entity-systems/
现在我想知道如何实现自动Node
创建时Component
添加到 Entity
在 C++ 中?请告诉我识别的原理是什么Nodes
可以从特定的 Entity
产生,即你应该有 Component
的列表和聚合组件的类。并且您应该了解可以使用数据列表创建哪些类。
例如我有 Components
:
class PositionComponent
{
int m_x;
int m_y;
int m_rotation;
};
class VelocityComponent
{
int m_vX;
int m_vY;
int m_vAngular;
};
class RenderableComponent
{
Sprite m_view;
};
class MoveNode
{
PositionComponent m_position;
VelocityComponent m_velocity;
};
class RenderNode
{
RenderableComponent m_rend;
PositionComponent m_position;
};
Entity
像这样:
Entity * e = new Entity;
e.add(new PositionComponent);
e.add(new VelocityComponent);
MoveNode
自动,如果我还添加这个:
e.add(new RenderableComponent);
RenderNode
被 build 。因此,当我删除它时:
RenderNode
应该删除。而这个过程当然不应该绑定(bind)到具体的
Nodes
和
Components
我已经定义了。
最佳答案
我有点困惑,因为它似乎混合了概念。我将尝试阐明这两个概念。
实体和组件
实体组件系统在游戏引擎中很常见,例如Unity就很明显地实现了它。试图解决简单继承在很多情况下效果不佳的问题,比如混合渲染和碰撞信息;是 Collidable
还有一个 Renderable
?而且由于多重继承对许多人来说是一件可怕的事情,而且在许多语言中都不支持,唯一的出路就是实体/组件设计。 (实际上不是唯一的解决方案,但这是一个不同的问题。)
实体组件的设计很简单,你有一个类Entity
接受多个 Component
类型的对象.会有多个组件“做”某事,比如 MeshRenderer
, TriMeshCollision
或 RigidBodyMotion
.如文章所述,实际逻辑不需要在组件本身中实现。该组件只是为特定逻辑“标记”实体。将实际工作委派在一个系统的紧密循环中是有意义的,甚至可能在不同的线程中完成,但稍后会更多。
然后组成实际的实体。有两种基本方法可以做到这一点,在代码中或在数据中。
例如,您在代表一个“真实世界”对象的代码中组合对象; Goblin
类型的对象存在并且它派生自类 Entity
.来自 Goblin
的构造函数然后将创建所有组件并将它们注册到自己身上。现在只对高级逻辑进行继承,例如 FastGoblin
源自 Goblin
并且只有不同的 Material 和速度设置。
创建对象的第二种方法是通过数据,即您拥有某种形式的对象描述语言。 (采用 XML 或 JSON 格式)然后这将在工厂方法中创建基于在此对象描述语言中定义的给定模板的内容。
基于节点的工作调度
拥有完全定义的对象但没有执行逻辑可能是有意义的。考虑服务器上或编辑器中的对象。在服务器上,您不希望渲染代码妨碍您。所以基本的方法是创建不包含数据的组件。要解决的问题是,如何在不迭代每一帧的整个场景并对周围的对象进行类型转换的情况下有效地完成任务?
您的第二个链接所描述的基本上是 Designing the Framework of a Parallel Game Engine 的拙劣版本
需要有一种方法来以有效的方式安排工作。建议的解决方案是让每个“节点”都执行特定任务。然后通过将节点提交给工作调度程序或特定系统来调度节点。
以渲染为例。你有一个实体,它有一个 MeshRenderer
成分。该组件将创建一个 RenderNode
并提交至 RenderSystem
.然后当需要渲染帧时 RenderSystem
将简单地迭代每个 RenderNode
并调用其显示方法。在 display 方法中完成了实际的渲染。
或者,系统、引擎或实体可以基于特定组件配置创建节点。以物理学为例。该实体具有 TriMeshCollision
和 RigidBodyMovement
成分。 PhysicsSystem
看到这个配置会创建一个 RigidBodyNode
它将两个分量作为输入,从而实现刚体运动。实体是否应该只有 TriMeshCollision
组件PhysicsSystem
然后会创建一个 StaticColliderNode
来实现行为。
但就像从数据构建组件的机制一样,节点也可以通过工厂函数创建并附加到实体。这可以是对象定义或基于规则的系统的一部分。
将此设计映射到 C++ 应该很简单。相当困难的一点是找出不同位如何连接的方式;例如,如何MeshRenderer
可以访问 RenderSystem
所以它可以提交它的RenderNode
.但这可以通过单例(颤抖)或传递 Game
来解决。/Engine
周围的对象 Entity
或 Component
.
这是好的设计吗?
但我想在这里解决的问题是:这是好的设计吗?
我对你的第二个链接(游戏和实体系统)有问题,因为我认为设计很快就会落空。对于物理等其他方面也是如此,但在考虑现代 3D 渲染时,这将变得非常低效。
当您需要在空间上组织场景以有效地剔除隐藏对象,将对象组织成批次进行照明并减少资源切换时,整个“节点列表”概念就没有实际意义,因为无论如何您都需要一个单独的组织结构。
此时,您可以让组件直接与系统“对话”,并且每个系统都有适合其特定用途的独特的特定 API。渲染、声音和输入的要求各不相同,将它们塞进 API 是徒劳的。
也可以看看
关于c++ - C++ 中的实体系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21221992/
我有这个代码: System.err.print("number of terms = "); System.out.println(allTerms.size()); System.err
我有以下问题:在操作系统是 Linux 的情况下和在操作系统是 MacOs 的情况下,我必须执行不同的操作。 所以我创建了以下 Ant 脚本目标: /u
我正在调用 system("bash ../tools/bashScript\"This is an argument!\"&"),然后我正在调用 close(socketFD) 直接在 system
使用最初生成的随机元素来约束随机数组的连续元素是否有效。 例如:我想生成一组 10 个 addr、size 对来模拟典型的内存分配例程并具有如下类: class abc; rand bit[5:0
我正在创建一个必须使用system(const char*)函数来完成一些“繁重工作”的应用程序,并且我需要能够为用户提供粗略的进度百分比。例如,如果操作系统正在为您移动文件,它会为您提供一个进度条,
我即将编写一些项目经理、开发人员和业务分析师会使用的标准/指南和模板。目标是更好地理解正在开发或已经开发的解决方案。 其中一部分是提供有关记录解决方案的标准/指南。例如。记录解决/满足业务案例/用户需
在开发使用压缩磁盘索引或磁盘文件的应用程序时,其中部分索引或文件被重复访问(为了论证,让我们说一些类似于 Zipfian 分布的东西),我想知道什么时候足够/更好地依赖操作系统级缓存(例如,Debia
我们编写了一个 powershell 脚本,用于处理来自内部系统的图像并将其发送到另一个系统。现在,业务的另一部分希望加入其中,对数据进行自己的处理,并将其推送到另一个系统。打听了一下,公司周围有几个
我正在尝试朗姆酒我的应用程序,但我收到以下错误:System.Web.HttpUnhandledException:引发了“System.Web.HttpUnhandledException”类型的异
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
所以我在其他程序中没有收到此错误,但我在这个程序中收到了它。 这个程序是一个我没有收到错误的示例。 #include int main() { system("pause"); } // en
我在 c# System.URI.FormatExption 中遇到问题 为了清楚起见,我使用的是 Segseuil 的 Matlab 方法,并且它返回一个图片路径 result。我想为其他用户保存此
我正在尝试像这样设置文本框的背景色: txtCompanyName.BackColor = Drawing.Color.WhiteSmoke; 它不喜欢它,因为它要我在前面添加系统,例如: txtCo
请帮助我解决 System.StackOverflowException我想用 .aspx 将记录写入数据库我使用 4 层架构来实现这一切都正常但是当我编译页面然后它显示要插入数据的字段时,当我将数据
我使用了一些通常由系统调用的API。 因此,我将 android:sharedUserId="android.uid.system" 添加到 manifest.xml, 并使用来自 GIT 的 And
我正在尝试创建一个小型应用程序,它需要对/system 文件夹进行读/写访问(它正在尝试删除一个文件,并创建一个新文件来代替它)。我可以使用 adb 毫无问题地重新挂载该文件夹,如果我这样做,我的应用
我想从没有 su 的系统 priv-app 将/system 重新挂载为 RW。如何以编程方式执行此操作?只会用 Runtime.getruntime().exec() 执行一个 shell 命令吗
我正在尝试制作一个带有登录系统的程序我对此很陌生,但我已经连续工作 8 个小时试图解决这个问题。这是我得到的错误代码 + ServerVersion 'con.ServerVersion' threw
当我“构建并运行”Code::Blocks 中的程序时,它运行得非常好!但是当我从“/bin”文件夹手动运行它时,当它试图用 system() 调用“temp.bat”时,它会重置。这是为什么?它没有
我想使用 system/pipe 命令来执行具有特殊字符的命令。下面是示例代码。通过系统/管道执行命令后,它通过改变特殊字符来改变命令。我很惊讶地看到系统命令正在更改作为命令传递的文本。 run(ch
我是一名优秀的程序员,十分优秀!