1

问题的背景

我正在开发一个基本的类似战舰的衍生游戏,我想随着时间的推移继续在 C++ 中添加功能(无图形)。目前我有一个 50 x 75 的游戏板,用char 类型的 2D 矢量(称为GameBoard )表示。我创建了一个游戏板并用“。”设置每个位置。字符。当您猜测坐标时,之前猜测的位置标有“-”,命中标有“X”


我的程序在哪里

我决定修改游戏以启用更多功能。我并没有走得太远,但是用伪代码勾勒出一个设计开始让我更多地思考如何进行这次升级。

我创建了一个名为Block (板上的空白区域)的类,而不是GameBoard是字符,它现在将具有 ax 和 y 坐标变量,以及一个用于直观显示正确字符的 char 变量。Block具有保存对象“ Feature ”的能力,该对象分解为“feature”的派生类。您可以滚动到最底部以获取有关这些类的更多详细信息。

这就是我的类层次结构树的方式:

                             feature 
                    item               vehicle
               gold     nuke                 plane

我需要什么帮助

我基本上有我想做的大纲/结构设置。现在我只需要一些帮助来启动它来连接一切。我在确定何时以及如何使用指针方面非常糟糕。

A.) 我应该更改GameBoard以保存Block类的指针吗?还是实际 的 Block对象?- Block会持有指向Feature或实际Feature对象的指针吗?

B.) 如何添加一个可以为空或给定值的特征变量?我只是将其设置为NULL吗?

C.) 我是否需要自定义复制构造函数来交换Block的Feature值?

D.)如果玩家使用Feature对象,我该如何从Block中移除?

E.)单个上偶尔会出现超过 1 个功能吗?

F.) 我如何声明BlockFeature类,以便Block可以容纳一个Feature并且Feature已经从另一个类派生(不包括在这篇文章中)。


关于我的课程的额外详细信息

所以 GameBoard 是将存储块的向量。块本质上是板上的各个空间。块包含其位置的坐标、表示它的字符以及持有Feature对象的可能性,但大多数时候Block不会持有特征。Feature源自 Block,在游戏中作为奖励奖励。因此,Feature分支为另外 2 个派生类,一个 Item Feature 或 Vehicle。等等。

当玩家选择坐标时,一个方法将转到 GameBoard 上/中的那个 Block,并首先检查 char 值是否表示之前未使用过的有效空间。然后它检查这个块的内容以获得特征。Feature 可能为空或包含派生的 Feature 对象。

好的,我的小说到此结束。抱歉写了这么多。我认为获得帮助的最佳方式是让帮助者知道发生了什么。请不要回应告诉我“直奔主题”。我知道我知道.. 如果我遗漏了细节,请告诉我。谢谢!

4

3 回答 3

1

我假设你想保持你的班级结构。在您的抽象点上,我建议通过(C++ 11 或 Boost)使用共享和 uniqe 指针。如果您不擅长指针,请了解 uniqe 和共享指针的工作原理并尝试坚持使用它们。请记住使对象的生命周期尽可能短。

A.) 我应该更改 GameBoard 以保存 Block 类的指针吗?还是实际的 Block 对象?Block 会持有指向 Feature 或实际 Feature 对象的指针吗?

我想将此 GameBoard 元素保留为不可变的 uniqe 指针或保留实际实例。

B.) 如何添加一个可以为空或给定值的特征变量?我只是将其设置为NULL吗?

您已决定将 Feature 保留在 Block 内 - 好的。如果是这样,请将其保留为共享指针。如果没有特征共享指针将为空。

C.) 我是否需要自定义复制构造函数来交换 Block 的 Feature 值?

仅当功能内部存在动态/不寻常的东西时。该功能将拥有什么?

D.) 如果玩家使用 Feature 对象,我该如何从 Block 中移除?

如果你使用共享指针没有问题。即使在处理之前的 Feature 过程中 Feature 发生了变化,当 GameBoard 不再需要 Feature 时,Feature 也会被正确处理并销毁。

E.) 单个块上偶尔会出现超过 1 个功能吗?

你必须问自己这个问题——你的游戏需要处理这种情况吗?如果是这样,只需保存指向特征的共享指针的向量/映射/集合/数组(取决于您的要求)。

F.) 我如何声明 Block 和 Feature 类,以便 Block 可以容纳一个 Feature 并且 Feature 已经从另一个类派生(不包括在这篇文章中)。

我不确定我是否正确理解了这个问题:

class Feature : public GameElement {
   /* Feature implementation */
}

class Block {
    shared_ptr<Feature> mFeature;  
    /* Block implementation */  
};

它回答了你的问题吗?

于 2013-04-05T11:08:07.233 回答
0
  1. 我不确定feature从类派生类是否是个好主意block
  2. 我宁愿feature在 的每个实例中使用一个指针block,这样NULL如果没有特性,指针就是指针。在您的情况下,此指针将是指向基类的指针feature。我鼓励使用virtual方法来访问单个功能。
  3. 当 afeature用完时,删除它并将指向它的指针设置为 NULL。(块实例中的指针)
  4. feature如果您想一次拥有多个block,请考虑使用某种数组/指针堆栈。
  5. 在我看来,GameBoard应该包含 s 的实际实例(而不是指针)Block
  6. 我不明白你的意思是:

我是否需要自定义复制构造函数来交换 Block 的 Feature 值?

我希望这会有所帮助=)。

于 2013-04-05T00:45:53.340 回答
0

我认为您的 GameBoard 是 GameObject 指针的容器是个好主意。您不需要创建一个全新的类并将其命名为 Block - 所有这些都是隐含的。也不需要跟踪块的坐标,因为它们是按顺序排列的。GameObject 将是游戏元素层次结构的基类 - 在您的情况下,这将是一个 Feature,我使用 GameObject 的原因是因为 Feature 描述性不是很好 - 这个术语太宽泛,范围很广。

当游戏开始时,您的 GameBoard 可以由空指针填充,这些空指针随后被创建并添加到棋盘的实际游戏元素替换。

如果您有动态分配的数据,您只需要实现复制构造函数和赋值运算符。如果没有,编译器将生成一个非常好的版本,可以进行原始对象复制。

话虽如此,您最好不要移动实际的对象实例,而使用建议的使用指针的方法,您只会移动指针,这更简单、更快。

如果要删除功能,只需删除实际对象并将其在板中的指针设置为空。

如果您实现父/子关系,您可以在每个块中拥有一棵游戏对象树,并且您可以递归地遍历该树并按照您的意愿对树元素进行操作。

一个设计良好的多态层次结构将允许您放置几乎任何东西,只要它是从您的基类派生的。

于 2013-04-05T01:58:37.197 回答