2010-10-18 109 views
2

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

到目前为止,一切都很好:有一个Camera类取决于Cube类,还有Cube类,它不依赖任何东西(在这个例子中)。

我得到一个问题,当我需要绘制一个立方体,或任何其他 - 以画点什么,需要的值它摄像机的观察矩阵中;这是我刚刚在第一段中计算出来的那个。实质上,这意味着当我在屏幕上绘制事物时,Cube类也变得依赖于Camera类,并且它们现在相互依赖。这意味着我要么:

  1. 需要使Camera类的View矩阵字段为静态,所以我可以直接从Cube类访问它。
  2. 需要在Cube类中创建一个方法(例如SetView),然后我可以从Camera类调用它(因为我已经有了它的参考)。
  3. 需要在外部范围内保留View矩阵。
  4. 需要进行双向依赖。

不过,我也不喜欢这些:

  1. 有多个摄像头,其处理多个视图(目前有在屏幕上,其中3),并可能有更多的(或更少)。
  2. 这会使代码略微(有时可能非常)不可读 - 例如,当我绘制立方体时,不太清楚View矩阵的来源,您只是有点使用它而不回头看。
  3. 我会从相机类访问外部作用域,或者外部作用域将访问相机,我不喜欢这样做,因为外部作用域仅用于处理执行机制。
  4. 我喜欢让我的参考字段“只读”,因为它目前在这个系统中的任何地方 - 引用是在构造函数中设置的,并且仅用于从引用的类中获取数据。

而且,如果我没有说清楚,让我重复说有多个Camera对象和多个Cube对象;而任何相机可能依赖于任何Cube,也可能不依赖任何Cube,但通常至少有一个依赖于Cube的相机。

任何建议,将不胜感激:)

回答

2

如果您的Cube必须知道如何渲染自己的相机(因此必须了解相机),那么相机可能无法知道如何将自己对准Cube。 Camera中当前的对齐行为可能属于像CameraDirector这样的更高级别的类,它知道Cubes和Cameras。这可以提高班级凝聚力,因为它将Camera的部分职责分解为一个不同的,重点突出的CameraDirector类。这让相机专注于其核心工作,并使其更易于理解和维护。

+0

感谢您的注意......在接受此回复之前,我必须先进行一些测试,但是您现在已将我的想法告诉了我应该做的事 - 在Camera.Attach(IAttachable attachTo)相机类,在那里我可以命令相机跟随该物体......在这种情况下,我会反转当前的依赖性。 – avance70 2010-10-19 07:07:47

+0

是的,我重新编写了这个部分,在我看来,目前为止最好的解决方案。 – avance70 2010-10-20 06:14:19

1

假设你DrawWorld()例行已经知道Cube S和Camera S,我会观察矩阵传递给CubeDraw()方法:

foreach (Cube cube in cubes) { 
    cube.Draw(..., mainCamera.ViewMatrix, ...); 
} 

那只有Cube“取决于”Matrix而不是Camera。再说一次,也许这违反了上面的规则3。但是,如果没有看到你的代码,我不能做得更好。

+0

这是我从一开始就使用的 - 那是当我只有一个相机。当我介绍多台摄像机时,我遇到了这个问题(将其视为赛车游戏中的后视镜)。所以这样处理它变得非常棘手:) – avance70 2010-10-19 07:04:50

1

另外两种选择:

  1. 创建相机和Cube基类不链接到对方,但仍包含大部分要使用的逻辑。然后,您可以将一个BaseCamera引用添加到多维数据集,您将为其分配一个Camera对象,而不是一个BaseCamera对象。 (和一个带有BaseCube字段的相机。)这是多态性的力量。
  2. 定义一个ICamera和ICube接口。然后,Camera类将使用ICube字段链接到多维数据集,反之亦然。

虽然这两种解决方案都需要您在创建和释放新相机和立方体对象时注意。我个人的偏好是使用接口。请记住,ICube和ICamera接口应该连接到彼此的而不是。他们的相关类将链接到另一个接口,但不是接口。

+0

谢谢,对象层次结构的工作有点棘手(让我们只是说它不在*我的*域进入问题),但如果你认为有问题解决方案中没有太多的对象层次结构。这是我不得不与其他参与者讨论的问题,我认为我们已经到了可以建立更好层次结构的地步,因为现在我们只有一些接口。 – avance70 2010-10-19 07:16:24

0

当做XNA我有一个类似的问题。

我通过向我的Draw方法接口添加一个接口到相机来解决它。

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

要得到的真正东西是你的更新和绘制循环是分开的。

当您绘制一个绘制对象的列表时,您的绘图例程会将一些相机类传递给它。

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

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

阅读关于控制反转。这是我所描述的真的。

1

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

在你的情况,你必须传递每个渲染方法的图形实例和相对于对象的观点。

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

+0

我也让每个类负责它自己的渲染:)感谢提醒我关于距离问题,我想我没有将这部分代码转移到新的解决方案中。 – avance70 2010-10-19 07:03:16