2014-02-26 38 views
4

在我的比賽,我已經定義了一個Screen類,包含了一些視覺Entity對象的引用,可以繪製到顯示器:里氏替換原則和一流的設計爲遊戲

class Screen { 
public: 

private: 
    std::vector<Entity*> entities_; 
}; 

所有Entity的,具有Draw()功能:

class Entity { 
    public: 
    void Draw(); 
    private: 
    int xpos; 
    int ypos; 
}; 

Screen的負責調用在其每個Entity S的Draw()功能。

問題在於一些(但不是全部)Entity也需要是可更新的,即隨着時間的推移它們將改變它們的外觀/位置。 Screen還需要調用Update()函數,但僅適用於可更新的對象

我的問題是:

是否有意義從Entity有一個更新的功能派生類:

class ChangingEntity : public Entity { 
    public: 
    void Update(int time); 
}; 

,並有Screen是這樣的:

class Screen { 
public: 

private: 
    std::vector<Entity*> entities_; 
    std::vector<ChangingEntity*> changing_entities_; 
}; 

如果我做了上述,然後我只調用Draw()爲每個Entity s和Draw()Update()每個ChangingEntity s。

或者 - 我應該只把Update()函數放在Entity,如果Entity對象不能更新,那麼Update()沒有實現?

+3

如果您知道如何將兩者靜態分開,然後分開容器。多態性適用於你*不知道你將要使用的靜態類型。 –

+0

你是什麼意思「如果你知道如何使兩者靜止分開......」你的意思是如果我能明確區分它們,並且事先知道它們是什麼類型?如果是這樣,那麼是的,我可以做到這一點。 – patchwork

+1

「從實體派生類是否有意義」 - 可能目前還沒有,因爲「實體」不適合用作基類。它有一個公共的非虛擬析構函數,這是個壞消息。對於基類,析構函數應該是虛擬的或者是保護的。 –

回答

3

有幾件事你可以在這裏加強;

最好不要讓實體繪製自己,使用單獨的Draw()函數或Drawable類(Single Responsibility Principle)。在你目前的方法中,你正在創建任何需要繪製的類來擴展實體,下次你會發現一個類不需要是可繪製的實體。所以使用一個單獨的繪圖功能。

其次你應該定義什麼是實體,例如Ogre3D定義Entityan instance of a discrete, movable object based on a Mesh,我沒有看到你當前的定義是足夠的,它只包含位置和繪圖函數。您可以將實體定義爲可更新對象,另一個名爲StaticEntity的類不需要多態性。讓場景有兩個單獨的列表,並且實際上能夠更新對象,再將渲染器與場景分開。

您的第三個Screen類應該被稱爲Renderer並且具有可以根據其靜態類型進行註冊的對象。您也可以有一個Drawable界面。