2010-10-18 108 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