c++ - 如何有效/正确地存储等距游戏的不同类(单个父类(super class)的所有子类型)的 map ?

标签 c++ game-engine isometric

<分区>

在过去的几周里,我一直在尝试利用业余时间开发一款等距的、基于图 block 的大亨风格的制作游戏(实际上只是为了看看我是否有能力),但我遇到了一个设计我正在努力应对的挑战。我已经使用 Tile 类(保存在 Map 类中)成功地实现了地砖并绘制它们等等,但我现在希望能够在地砖上添加对象。

我已经能够使用相当笨重的调试类来创建和呈现对象(如表格),该调试类作为 std::map<int, Object> 包含在 Map 类中。并为对象提供 X/Y 坐标,以便 Map 可以将它们呈现在正确的位置。所有这一切,虽然可能不是最好的方法,但在我尝试子类化对象以赋予它们不同的功能之前都是有效的。

我曾(错误地)假设我能够为 map 上的所有对象提供某种异构容器,我可以在游戏循环中循环并运行特定于对象类型的逻辑。我还没有完全确定游戏的范围,所以目前我只是给不同的对象不同的成员变量——比如一个有容量的容器对象,一个有能量等级的加热器对象,等等。我的第一个测试是能够将项目放置在 map 上,然后能够查询容器对象的所有容量的总和 - 只是为了确保它在继续下一步之前有效.

我一直在尝试使用 OpenTTD 和一些 Habbo Hotel 模拟器等开源项目来解决所有这些问题,但无济于事。我很想听听其他人认为解决这个问题的最佳方法是什么。

我试验过 dynamic_cast在我的 map 中使用指针,但从我看到的其他答案来看,这似乎不是一个特别好的方法。我是否应该创建一个相同类型的对象池,然后在游戏循环期间遍历每个池以使事情变得更简单?

最佳答案

标准解决方案是将它们存储为指向具体对象的基类指针。

如果你有

class IObject
{
public:
    virtual void render() const = 0;
    virtual ~IObject(){}
};

你可以

int main()
{
    using IObjectUP = std::unique_ptr<IObject>;
    std::map<int, IObjectUP> m;

    // some concrete objects get created

    for (const auto& [_, o] : m)
        o->render();
}

std::unique_ptr 的使用假定所有权。如果其他人拥有一个对象,您可以选择使用 std::shared_ptrstd::weak_ptrstd::reference_wrapper

还有一件事。 std::vector 是默认容器。如果没有充分理由使用 std::map,请使用 std::vector

关于c++ - 如何有效/正确地存储等距游戏的不同类(单个父类(super class)的所有子类型)的 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57484900/

相关文章:

c++ - 锁定映射和 vector 以防止从两个线程访问

java - 游戏专用3D环境系统

c++ - 如何连接 2 个 LPOLESTR

c++ - 如何做更简单的 UT kismet 版本(C++ 和 Lua)

c - 打印数组时如何显示不同的字符? (C语言)

java - 等距排序的比较误差

javascript - 为什么我的线不匹配?

python - 如何在 Python 中渲染一个等距的基于图 block 的世界?

c++ - 替代 IF 语句和 switch case

c++ - 命名空间范围内的运算符隐藏全局范围内的另一个运算符