2

我正在将基于 tile 的 2D 游戏迁移到 C++,因为我真的不是 Java 的粉丝(有些功能很好,但我就是不习惯)。我正在使用 TMX 平铺地图。这个问题是关于如何将对象定义转换为实际的游戏实体。在 Java 中,我使用反射来分配指定类型的对象(假设它派生自基本游戏实体)。

这工作得很好,但是这个特性在 C++ 中不可用(我明白为什么,我没有抱怨。我发现反射很乱,我很犹豫在 Java 中使用它,哈哈)。我只是想知道翻译这些数据的最佳方法是什么。我的想法是一个基类,所有实体都可以从中派生(这似乎很标准),然后让加载程序根据 TMX 映射中的“类型”值分配派生类型。我想了两种方法来做到这一点。

  1. 一个巨大的开关盒块。冗长而恶心。我怀疑是否有人会提出这个建议(但这是显而易见的)。
  2. 使用 std::map,它将任意类型名称映射到函数以分配与所述类型名称相对应的所述类。
  3. 最后,我曾想过制作一个基类的实体,并为不同的实体类型使用脚本。脚本本身会向系统注册它们的实体类型,尽管游戏需要在加载时加载所述实体类型脚本(这可以通过一个主要的实体类型声明脚本来完成,这将使每个实体的编辑数量减少到 2 :实体创建和实体注册)。

虽然选项二看起来不错,但我不喜欢为每种类型更改 3 段代码(定义实体类,定义分配函数,并将函数添加到 std::map)。选项 3 听起来不错,除了我认为的两件事:我害怕纯脚本驱动实体的速度。另外,我知道将脚本添加到我的引擎本身将是一个大项目(添加所有与库交互的辅助函数会很有趣)。

有谁知道更好的解决方案?也许不是更好,但只是更清洁。每个实体类型的代码编辑更少。

4

1 回答 1

2

如果您使用自注册到工厂,则可以减少解决方案 2 中的代码更改次数。缺点是实体知道这个工厂(自我注册)并且这个工厂必须是一个全局(例如单例)实例。如果这对您来说没问题,那么这种模式会非常好。每种新类型只需要编译一个新文件的链接。

您可以像这样实现自我注册:

// foo.cpp
namespace 
{ 
  bool dummy = FactoryInstance().Register("FooKey", FooCreator); 
}

抽象工厂,模板风格,Jim Hyslop 和 Herb Sutter 着

于 2012-05-13T05:05:43.727 回答