两个类相互依赖

时间:2010-10-18 13:55:49

标签: c# class xna dependencies bidirectional

我有Camera类,它处理相机行为。其中的字段是对目标的Cube类的引用(Cube只是其中一个对象,但我不会提到其他人保持简单)。为了计算视图矩阵,我需要摄像机的位置和目标的位置,所以我可以向我的程序解释:“摄像机放在这里,从这里开始看这个立方体”。如果立方体碰巧移动,摄像机的视角也会自动改变。

到目前为止,一切都很好:有一个依赖于Cube类的Camera类,而且Cube类依赖于什么(在本例中)。

当我需要绘制一个立方体或任何其他其他时 - 我得到一个问题,为了绘制一些东西,在所需的值中它是相机的View矩阵;那是我刚刚在第一段中计算的那个。从本质上讲,这意味着当我到达屏幕上绘制内容时,Cube类也会依赖于Camera类,并且它们现在彼此依赖。这意味着我要么:

  1. 需要将Camera类的View矩阵字段设置为静态,因此我可以直接从Cube类访问它。
  2. 需要在Cube类中创建一个方法(例如SetView),然后我可以从Camera类调用它(因为我已经有了它的引用)。
  3. 需要在外部范围内保留View矩阵。
  4. 需要实现双向依赖。
  5. 但是,我不喜欢其中任何一个:

    1. 有更多相机可以处理多个视图(目前屏幕上有3个视图),可能会有更多(或更少)。
    2. 这使得代码略微(有时,可能,非常)不可读 - 例如,当我绘制立方体时,不太清楚View矩阵来自何处,你只是有点使用它而不回头
    3. 我会从相机类访问外部作用域,或者外部作用域会访问相机,我不喜欢这样,因为外部作用域仅用于处理执行机制。
    4. 我喜欢将我的引用字段保持为“只读”,因为它在本系统中当前无处不在 - 引用在构造函数中设置,仅用于从引用的类中获取数据。
    5. 而且,如果我还没有说清楚,那么让我再说一遍,有多个Camera对象和多个Cube对象;而任何相机可能或可能不依赖于任何立方体,但通常至少有一个相机依赖于立方体。

      任何建议都将受到赞赏:)

5 个答案:

答案 0 :(得分:2)

如果您的Cube必须知道如何相对于相机渲染自身(因此必须了解相机),那么相机可能无法知道如何将自身与多维数据集对齐。当前在Camera中的对齐行为可能属于更高级别的类,比如知道Cubes和Cameras的CameraDirector。这提高了类的内聚力,因为它将Camera的一些职责分解为一个不同的,紧密聚焦的CameraDirector类。这使相机可以专注于其核心工作,使其更易于理解和维护。

答案 1 :(得分:1)

假设您的DrawWorld()例程已经知道CubeCamera s,我会将视图矩阵传递给Cube的{​​{1}}方法:

Draw()

那样foreach (Cube cube in cubes) { cube.Draw(..., mainCamera.ViewMatrix, ...); } 仅“依赖”Cube而不是Matrix。然后,也许这违反了上面的规则3。但是,如果不看一些代码,我就无法做得更好。

答案 2 :(得分:1)

两个备选方案:

  1. 为Camera和Cube创建基本类,这些基类不会相互链接但仍包含您要使用的大多数逻辑。然后,您可以向Cube添加BaseCamera引用,您将为其分配Camera对象,而不是BaseCamera对象。 (以及带有BaseCube字段的相机。)这是多态性的力量。
  2. 定义ICamera和ICube接口。然后,Camera类将使用ICube字段链接到多维数据集,反之亦然。
  3. 但是,这两种解决方案都要求您在创建和释放新的相机和立方体对象时要小心。我个人的偏好是使用接口。请记住,ICube和ICamera接口应链接到彼此。他们的相关类将链接到其他接口,但不链接到接口。

答案 3 :(得分:1)

我让每个对象类负责它自己的渲染。

在您的情况下,您必须将每个渲染方法传递给图形实例和相对于对象的视点。

绘图类可以访问所有对象类的实例,并以任何有意义的顺序调用每个对象的绘图方法。您的对象类可能必须有另一个方法来确定与视点的距离,以便您可以以最远到最接近的顺序调用绘图方法。

答案 4 :(得分:0)

在做XNA时,我遇到了一个小问题。

我通过将相机的界面添加到我的Draw方法界面来解决它。

它不漂亮,相机随处可见,但效果很好。

真正需要的是你的更新和绘制循环是分开的。

绘制你时要绘制的对象列表,你的绘图例程有一些相机类传递给它。

以类的方式编写代码的替代方法,以生成需要渲染的所有对象的列表。将其传递给包含相机的渲染器。

重点是保持摄像机列表以及可绘制对象列表,尽管所有这些对象也属于描述游戏状态的逻辑模式。

了解控制反转。这就是我所描述的全部。