1

所以我正在开发一个 2D 空间模拟器,并且我有资源管理器' calc'来处理所有计算。例如,来自calc.hpp

var calc::eccentricity (object A, object B);
var calc::distance     (object A, object B);
var calc::orbitV       (object A, object B);

等等。但是,我的程序结构方式是在我的calc课堂上

private:
object *ship    //the currently controlled ship
object *targ    //target
object *ref     //reference (from which speeds, position, etc. are calculated)

为了使用第一个示例中给出的计算,我为每个计算函数编写了三个函数,如下所示:

var calc::ship_ecc      (object A){
    if(!ship)    //catches null pointers
        return NAN;
    return eccentricity(*ship, A);
}

var calc::ship_ref_ecc  (){
    if(!ref)    //catches null pointers
        return NAN;
    return ship_ecc(*ref);
}

var calc::ship_targ_ecc (){
    if(!targ)   //catches null pointers
        return NAN;
    return ship_ecc(*targ);
}

对于eccentricity,然后对于distance和也是一样的orbitV。所以我最终为每个计算提供了四个函数。正如你所看到的,calc.hpp这会产生大量重复的代码。重复的代码是一件坏事。

我的问题是

有什么方法可以打电话

calc.ship.targ.eccentricity();
calc.ship.ref.eccentricity(); //or variation thereof

或者

calc.ship.targ(eccentricity);
calc.ship.ref(eccentricity);  //or variation thereof

代替

calc.ship_targ_ecc();
calc.ship_ref_ecc();

? 我想知道你是否可以做一些花哨operator()的重载,或者传递一个函数,或者friendcalc. 理想情况下,我应该只能访问31 - 53所有线路public

谢谢!

编辑:有一个例子:https ://ideone.com/jypJQS这是它应该输出的内容以及它现在是如何工作的

4

3 回答 3

1

这可能需要一些重构,但我认为这是值得的。对于简单的游戏,您可以使用 OOP 和多态来解决问题。

首先,创建一个object类。

 class Object {

 public:
    Object();
    ~Object();
 };

这个对象类将成为游戏中所有对象(船、角色等)的基础。然后,您将为您的ship.

 class Ship : public Object {


 };

这将允许轻松扩展到需要相同原理的未来对象。

在对象类中,您将拥有一些基本属性:

  • 物理(可选)
  • 方面
  • 速度(最后计算的速度)
  • 受控(布尔 - 当前控制船与否)

calc这将消除与andship类建立硬关系的需要。

接下来,您将更改您的calc班级以成为一般班级。您不想依赖单个船舶对象,这很麻烦。

选项1

calc您可以为每个对象创建一个类的实例。该calc实例可以访问objectandship类的已有属性。

选项 2

创建一个通用calc类,要求您传递对船/对象实例的引用。calc->eccentricity(&ship, target);

选项 3

在一个可能的manager类或一个简单的“全局”变量中。您可以引用当前控制的船(如果这是您的系统的工作方式,我不确定)。或者您可以存储船的索引,并且所有实例都保存在vector<&Ship>.

在一个简单的游戏中,直接的 OOP 就足够了,但如果你想要更多的解耦,基于组件的游戏设计将是一个更好的选择(当然,结合 OOP)。

于 2012-12-24T22:28:37.390 回答
1

也许这改变了你当前的代码太多。但我认为 calc 中的函数应该是 object 的成员。所以你可以这样:

ship.eccentricity(target);

让我感到困惑的是(这里可能是最大的问题)是您似乎在 calc 对象(私有成员)中定义了一些硬关系。那些是为了什么?从代码中,我猜每个“船”都有一个 calc 对象。如果是,那么将代码添加到对象而不是维护对象和计算之间的 1-1 关系将是另一个原因。

于 2012-12-24T22:09:23.427 回答
0

所以我把它交给了/r/learnprogramming,我从 zzyzzyxx 那里得到了一个很好的答案(一如既往)。他的回答:

简单地使用需要两个或三个参数的函数有什么问题?他们不必在任何特殊calc班级。也许是一个calc命名空间。我不确定这对您的其他设计是否有意义,但是如果没有合理的默认值,那么将其设为成员函数以便任何东西都可以计算出它需要的目标和潜在的参考点呢?

所以基本上,不用担心这一切calc.eccentricity(A, B),,生意,只是calc.ship_ecc(A)calc.ship_ref_ecc()

calc.eccentricity(*calc.targ(), B)

另外,不要做calc一个单例,让它成为一个命名空间。
我现在就去做。

于 2012-12-25T01:13:14.970 回答