c++ - 组件之间如何有效通信?

标签 c++ sfml

我正在设计一个基于组件的系统并且一切正常,但是缺少一个关键特性,那就是能够从一个对象类型的类中获取一种类型的组件,可以添加这个类/删除的组件。在 Object 类中,存在一个组件 vector :

vector<Component*> pComponents;

而在 Component 类中,Component 必须有一个名称。因此,像 Drawable 这样的组件将被这样调用:

pPlayer->addComponent(new Drawable("Drawable"));

这就是播放器可绘制所需的全部内容。现在的问题是:在添加大量依赖于其他组件的组件时,组件之间的通信方式是否有解决方案?

目前,在我的 Game 类中(它不是 Object 类型,虽然我可能让它从 Object 派生,但不确定这是否是一个好的设计决策)我在更新函数中有这个代码:

void Game::update()
{
    pPlayer->update(0);

    pSpriteLoader->getSprite()->move(pPlayer->getVelocity());
}

我使用 SFML2 完全是因为它很容易用于 2D 图形。播放器更新函数调用组件各自的更新函数。 Sprite 加载器也是一个组件,它负责通过可以从文件或内存中读取的纹理/图像来处理 Sprite 的加载。如果我省略这行代码,那么 Sprite 将无法在屏幕上移动。如您所见,pPlayer 有一个 getVelocity() 函数很奇怪,这是因为我没有将所有物理内容移动到它自己的组件中。可怕的是,一旦我将 Player 类中的物理内容移到 Physical 组件类中,我怎样才能让这些组件相互通信,而不必求助于上述代码行?

我的解决方案是创建一个组件管理器来注册每个组件,任何需要另一个组件的组件都必须咨询该组件管理器,而不必直接这样做。这是否是一个可行的解决方案,那么我如何才能继续执行此类组件管理器的逻辑?

最佳答案

好吧,我想你会从设计消息系统开始。

您似乎希望大量解耦代码并尽可能多地创建组件。我想这很好,但是在没有耦合的情况下拥有依赖关系的答案可能是消息传递中的一些东西。

假设您需要一个成就系统。这是一个完美的系统示例,需要将其手伸入尽可能多的角落和缝隙,以便在设计成就时实现最大的灵 active 。但是你怎么能同时 Handlebars 伸进物理、人工智能和输入系统而不是写意大利面条式的代码呢? 答案是将监听器放在事件队列中,然后根据消息内容按特定标准运行它们。

因此对于每个组件,您可能希望继承一个通用的消息发送/接收组件,可能使用泛型,以便发送数据消息。例如,假设您在 FPS 游戏中发射激光。激光很可能会发出声音,而激光很可能需要动画。您可能希望向声音系统发送消息以播放某种声音,然后向物理系统等发送消息以模拟激光的效果。

如果您有兴趣,我有一个非常非常粗糙的库,用于基于队列、监听器和通用消息对事件系统进行建模:https://github.com/VermillionAzure/Flexiglass您可能会从其他新手代码中获得一些见解。

我真的建议也看看 Boost.Signals2 或 Boost.Asio。信号/网络知识通常有助于设计通信系统,即使系统只是位于游戏组件之间。

关于c++ - 组件之间如何有效通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30992779/

相关文章:

c++ - 通过 `IShellItem`获取文件大小

c++ - 附加 Char 改变其大小后的字符串

c++ - 如果我要用它构造一个对象,我应该 move 被调用者的返回值吗?

c++ - 奇怪的 undefined reference 错误

c++ - 未解析的外部符号 sf::Time with SFML

c++ - 是否可以使用 std::pair 作为关联容器(如 std::map)的(唯一)模板参数?

c++ - 尽管类型删除,是否可以使用静态多态性(模板)?

链接 sfml-audio 时的 C++ undefined reference

c++ - 将一个旋转的矩形拆分成更小的矩形,如何旋转它们以保持原来的大矩形?

C# .Net 库在 Linux 上找不到依赖项