我想實現某種「只是換了我」的遊戲引擎和問題的情節去的方式如下:C++遊戲設計及多態性問題
假設我有一個可呈現實體的一些抽象接口,例如IRenderable
。
而且它聲明的方式如下:
interface IRenderable {
// (...)
// Suppose that Backend is some abstract backend used
// for rendering, and it's implementation is not important
virtual void Render(Backend& backend) = 0;
};
我在做什麼,現在是像類似聲明
class Ball : public IRenderable {
virtual void Render(Backend& backend) {
// Rendering implementation, that is specific for
// the Ball object
// (...)
}
};
不同的類,然後一切都看起來不錯。我可以輕鬆地做類似std::vector<IRenderable*> items
,推動在這個載體的一些項目,如new Ball()
,然後撥打電話類同foreach (IRenderable* in items) { item->Render(backend); }
好吧,我想這是「多態」的方式,但如果我想有不同的類型是什麼對象在我的遊戲中,並有能力操縱他們的狀態,每個對象都可以通過它自己的界面進行操作?
我可以做類似
struct GameState {
Ball ball;
Bonus bonus;
// (...)
};
,然後輕鬆地通過自己的方法改變對象的狀態,像ball.Move(...)
或bonus.Activate(...)
,其中Move(...)
是具體的只有Ball
和Activate(...)
- 只爲Bonus
實例。
但在這種情況下,我失去了編寫foreach IRenderable*
的機會,僅僅是因爲我將這些球和獎金存儲爲其派生的基類的實例。而在這種情況下,渲染過程變成像
ball.Render(backend);
bonus.Render(backend);
// (...)
很亂,因爲我們實際上失去了多態性這樣(沒有實際需要作出Render
功能虛擬等
另一種方法是壞是指通過調用或dynamic_cast
與typeid
東西向下轉型,以確定要處理的對象的類型,這看起來更糟糕,我和這也打破了這種「多態」的想法。
所以,我的問題是 - 是否存在某種(可能)替代方法來實現我想要做的事情,或者我的當前模式可以以某種方式修改,以便我實際存儲IRenderable*
用於我的遊戲對象(以便我可以在其中每個對象上調用虛擬Render
方法)同時保留輕鬆改變這些對象狀態的能力?
也許我做的事情從一開始絕對錯誤的,如果是的話,請指出來:)
提前感謝!
有人知道一些有效的C++方法來通過這些Renderable項目來實現第二個循環,這隻會找到Movable對象的子集嗎? 要麼我很愚蠢或這隻能通過調用動態鑄造/ typeid /您自己的RTTI實施... 感謝回答:) – 2010-04-23 00:25:17
@Kotti只是創建他們的另一個列表。例如。你有一個可移植的列表,一個Movables列表,一個收藏列表。然後,任何時候你想操作任何子集,只要遍歷適當的列表。 (再次 - 將Renderables添加到Renderable構造函數中的可渲染列表中。) – 2010-04-23 18:58:16