2

所以,我有一个关于 C++ 的问题。假设我有一个游戏的敌人类。我希望能够(理论上)在我的游戏中拥有无限数量的敌人。所以我必须有每个类的多个实例,并且我需要能够分别访问这些实例。我是否必须拥有一个具有无限空间的敌人对象数组,并且我会使用 new 和 delete 运算符来创建和删除数组中的敌人?那么我需要一个变量来保存敌人的数量,对吗?

4

7 回答 7

5

使用std::vector. 它将根据需要自动分配更多内存。

标准库中还有其他容器会在需要时自动分配内存,例如std::liststd::setstd::map. 这些容器可能更适合特殊情况,但std::vector通常是最佳选择。这一切都取决于实施细节。

你可以像这样使用它:

#include <vector>

struct Enemy {
    //...
}

std::vector<Enemy> v;

Enemy e1, e2;
v.push_back(e1);
v.push_back(e2);

std::cout << "First enemy in vector: " << v[0];
于 2013-04-23T20:05:15.610 回答
2

已经回答了什么样的数据结构的答案:

标准::向量

这还没有从游戏编程的角度得到解答,所以就这样吧。

如果您使用像 Vector 这样的数据结构而不考虑要存储的对象数量,您将很快遇到问题。

大多数游戏循环都会更新数组中的每个“角色”对象。如果您担心“无限”角色,您可能不想在游戏的更新功能中更新每个角色。

如果您只有几个字符或可管理的数量,那么 Vector 就可以了。

但是,如果您要拥有一个包含数百或数千个字符的世界。Vector 不再是您想要使用的数据结构。

在这种情况下,您将更适合称为四叉树(2d)或八叉树(3d)的东西。这些数据结构的解释超出了这个答案的范围。只要知道它们在游戏方面会更有效率。

于 2013-04-23T20:13:26.770 回答
1

您可能想使用标准库中的容器。最好的开始可能是来自标准库的vector 。它就像一个数组,但会根据您添加到其中的项目数进行扩展。这样你就不会浪费任何空间。

根据您的具体要求,还有其他具有不同性能特征的容器。但是向量通常是一个很好的起点。是挑选标准容器的一个很好的参考。

于 2013-04-23T20:05:53.057 回答
1

在 C++ 中,std::vector<>是用于动态调整大小数组的数据结构。我将从敌人的向量开始。

class Enemy { ... };

std::vector< Enemy > enemyCollection;

vector数据结构将为您处理内存管理。请参阅http://www.cplusplus.com/reference/vector/vector/以供参考。

于 2013-04-23T20:06:27.770 回答
1

这就是我们在 C++ 中使用容器的原因:vector、list、deque 和许多更专业的容器(例如 map、关联容器)。

它们能够根据需要增长和缩小,您可以轻松添加和删除项目。您使用哪一个取决于您的确切需求(查找复杂性、随机访问、插入复杂性......)。

正如其他人所提到的,如果您不习惯标准容器,向量可能是一个不错的起点,并且随着时间的推移,您将学会为正确的工作选择正确的容器。

于 2013-04-23T20:06:32.400 回答
1

我是否必须拥有一组具有无限空间的敌方对象?

我会说这很可能是个主意。根据这些“敌人”的设计和性质,您可能不需要一直将所有这些“敌人”的所有数据都保存在内存中……当内存不足时,您的游戏会发生什么?

每个敌人的物体真的需要完整的物体吗?看一下享元设计模式。我猜你并不真的需要一次拥有所有这些。

与单个敌人字面上对应的敌人类实例的概念可能是您错误的地方。

其他潜在模式包括代理和原型。

我会使用 new 和 delete 运算符来创建和删除数组中的敌人吗?

取决于您的实施。如果你 malloc/new 你必须释放/删除。这是微不足道的,与您放入对象的容器无关,而是取决于创建过程。

请记住,如果您在游戏中并且必须不断调用 malloc/new 来创建敌人,那么您的游戏性能将会很糟糕。每次您将前往操作系统的系统调用,一次只能授予一个线程,如果一次在不同的线程上发生一堆,您将获得很多延迟,这可能对您而言可能或可能无关紧要;给出上下文我会假设这对你来说并不重要,但为了其他人,我还是提到了它。我建议弄清楚你大概需要多少内存并事先获得所需的所有内存,如果你用完了,请求两倍的内存......但这是关于内存管理的一个完全独立的话题......这实际上与您的数据结构和构造范式几乎没有关系。

那么我需要一个变量来保存敌人的数量,对吗?

取决于您如何存储它们。如果您使用的是 c-array,那么您是在管理自己。大多数正式容器都有相当有效的方法来获取它们的大小。但两者之间可能有一些警告。

但是,鉴于您要问这个问题,我认为您真的应该从直接的实现细节和代码行中退后一步,看看您正在组合的更高级别的架构,这些架构似乎没有经过深思熟虑或理解。“开始就要考虑如何结束”

任何人都不可能以有价值的方式以当前形式明确回答您的问题。看来您真正的问题是:

  1. 什么是容器,它们是如何工作的?
  2. 管理这些大量敌人的有效范例是什么(认真从四人组的设计模式中查找 FlyWeight)
  3. 我应该如何构建我的数据结构?

关于 1:这个网站上有大量关于数据结构的问题/答案,还有大量关于现有数据结构的书籍和文档。STL 提供了几十个,Boost 也是如此。我不打算在这里重复。

关于 2. 正如我所说,您需要查看众所周知的模式来解决这个问题。我在上面给出了一些建议。如果没有更多信息,这是我可以提供的最普遍有用的信息,可能对其他人有用。

关于 3. 如果您坚持使用离散项,我认为您可能应该考虑使用工厂方法或抽象工厂或类似的东西,这样您就不必在处理内存分配失败并且无法实例化时乱扔代码敌人。

于 2013-04-23T21:35:54.383 回答
0

只需使用 std::vector; 它是一个无限边界的动态数组。

于 2013-04-23T20:05:47.640 回答