2013-12-10 17 views
1

我正在嘗試開發簡單的TowerDefense遊戲,但是 好像我錯過了OOP的基礎知識,因爲我遇到問題 必須以某種方式解決因爲每個在OOP中編程的人都必須有 的參與。好的做法是從另一個不是兒童的類中找到一個類的現有實例

這裏是非常非常基本的結構

Game 
|__ Map 

Player 
|__ UnitController 

+ Block 
+ Unit 

所以基本上Map()控制器創建100 new Block()傳遞x and y座標,它那些Blocks()一個List<>內 和存儲信息。其中之一Block正在開始 的位置(它仍然是一個Block對象)。

現在UnitController()SpawnUnit()方法。它創建了new Unit(),它(這裏出現問題) 必須將此單元實例設置爲啓動塊。爲了做到這一點,UnitController將不得不 要求Map爲起始位置(這是一個變量存儲由Map),但.. 如何UnitController 可以聯繫Map實例。我看到的唯一方法是Map是一個單身人士,我只需要做Map.getStartingPos 否則如果Map不是單身人(因此是實例),那麼UnitController將如何找到這個實例? 我可能當我實例化UnitController時,將此實例傳遞給UnitController,但這不是一個選項,我猜 ,因爲在這個遊戲中會有其他的例子(比如塔的攻擊單位,它必須找到一個單位, ...) 我不能簡單地將這些實例全部放在代碼中?

感謝

回答

3

你爲什麼反對給UnitController參考其Map

public UnitController { 

    private final Map map; 

    public UnitController(Map map) { 
     this.map = map; 
    } 
} 

現在你UnitController具有對Map參考。如果你仔細想想,這是有道理的。什麼單位可以控制沒有地圖? UnitController是不是所有的Map都是控制單元?它作爲一種財產是有道理的,不是嗎?

正如你所建議的那樣,你當然不想讓Map成爲一個單例,因爲這樣會打破模型的優雅面向對象。整個要點是能夠有多個Map s,多個UnitController可以在其上作用。一次只限制一次運行一次,一次執行Map,使代碼比面向對象程序更加流程化。

不管你做什麼,在MapUnitController必須有東西共同以共享數據,即使你不希望他們有彼此直接引用。至於「襲擊最近的單位的塔」是不使用這個模型的原因,它是沒有意義的; Tower應該簡單地請求來自Map對象的最近單位(即,map.getNearestUnit(int x, int y))。只要所有東西都可以從Map推送和提取信息,就不需要任何更復雜的引用。

對於螺紋Tower你關心的更復雜的例子:

public class Tower extends Unit implements ActionListener { 

    private final Timer fireTimer; 
    private final Map map; 
    private int damage; 
    private int range; 

    public Tower(Map map, int damage, int range, int fireRate) { 
     this.map = map; 
     this.damage = damage; 
     this.range = range; 
     fireTimer = new Timer(fireRate, this); 
     fireTimer.start(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == fireTimer) { 
      map.damageNearestUnit(this, range, damage); 
     } 
    } 

} 

...其中用於map.damageNearestUnit簽名是一樣的東西damageNearestUnit(Unit unit, int range, int damage)。這本質上應該採取在Unit通過,得到它的座標,並在int range找到最近的單位。如果存在範圍內,則將int damage交易給其他單位。然後,如果損壞的Unit具有小於1周的健康,應該從Map刪除,引發UI變化等

其實,如果我有簡單的getter和setter我Tower和有我damageNearestUnit方法假定一個部隊正在破壞另一個,我可以簡單地簽名爲damageNearestUnit(Unit attacker)

我希望這可以顯示Map是如何將所有其他東西結合在一起並控制存在於其上的結構的結構。

+0

謝謝傑夫。我擔心隨着遊戲的擴展,我會發現當我開始使用線程時非常不方便,我必須將地圖/單位對象傳遞給每個塔線,以便它們可以造成傷害,減速單位等。 – Mike

+1

@Mike我建議你不應該把「單元」對象給一個「塔」。 「地圖」應該完成大部分重要工作。例如,在一個簡單的塔防遊戲中,你可以讓塔臺像'map.damageNearestUnit(int x,int y,int range,int damage)那樣調用',並讓'Map'處理其他所有內容。真的,你的'Tower'線程只負責在任何你的火速下增量調用這個方法。 – asteri

+0

@Mike但是,是的,必須爲該領域的每個對象提供對共享控制器的引用,將它們全部綁定在一起是有意義的。他們需要能夠互動。如果你把'塔'做成一個沒有參考'Map'的島,那麼'Map'可以改變'Tower'的狀態,但反之亦然。 – asteri

相關問題