我有下面的代碼,認爲簡單的射擊遊戲在C++:建模遊戲對象層次結構的最優雅和最有效的方法是什麼? (設計困擾)
// world.hpp
//----------
class Enemy;
class Bullet;
class Player;
struct World
{
// has-a collision map
// has-a list of Enemies
// has-a list of Bullets
// has-a pointer to a player
};
// object.hpp
//-----------
#include "world.hpp"
struct Object
{
virtual ~Object();
virtual void Update() =0;
virtual void Render() const =0;
Float xPos, yPos, xVel, yVel, radius; // etc.
};
struct Enemy: public Object
{
virtual ~Enemy();
virtual void Update();
virtual void Render() const;
};
// Bullet and Player are similar (they render and update differently per se,
/// but the behavior exposed to World is similar)
// world.cpp
//----------
#include "object.hpp"
// object.cpp
//-----------
#include "object.hpp"
兩個問題:
1,遊戲對象知道關於其他遊戲對象。
必須有一個知道所有物體的設施。它可能或可能不需要公開所有對象,它必須公開一些,取決於參數(查詢者的位置)。這個設施應該是世界。
對象必須知道他們所在的世界,以查詢碰撞信息和其他對象。
這引入了一個依賴關係,其中Object和World的實現都必須訪問對象的頭部,因此World不會直接包含它自己的頭部,而不是包含object.hpp(其中包含world.hpp)。這讓我感覺不舒服 - 我不覺得world.cpp應該在對object.hpp進行更改後重新編譯。世界並不覺得它應該與Object一起工作。這感覺像不好的設計 - 它如何被修復?
2,多態 - 能否也應該用於除代碼重用和遊戲實體邏輯分組以外的任何事情?
敵人,項目符號和玩家會更新和渲染不同,當然,因此虛擬Update()和Render()功能 - 相同的界面。它們仍然保存在單獨的列表中,其原因是它們的交互取決於兩個交互對象是哪個列表 - 兩個敵人彼此反彈,子彈和敵人相互破壞等。
這是功能這超出了敵人和子彈的實施;這不是我關心的地方。我覺得除了它們相同的界面之外,還有一個因素可以區分敵人,子彈和玩家,這可以並且應該以其他方式表達,允許我爲它們創建一個列表 - 因爲它們的界面是相同的!
問題是如何判斷包含在同一列表中的對象類別。 Typeid或其他形式的類型識別是不可能的 - 但接下來還有什麼其他方式可以做到這一點?或者,這種方法沒有錯?
謝謝你前兩段;這讓我感覺很有意義,也有助於清除我的頭腦。我已經重寫了我的問題,以澄清我想用多態性做什麼。 – zyndor 2009-09-23 09:37:30
訪客模式很棒,謝謝指出。我猜OnHit()方法類似於模式的Visit()方法,而Objects就是他們自己的訪問者,對吧? – zyndor 2009-09-24 15:59:18
選擇一個答案接受爲最好的答案是困難的,因爲他們都有很好的積分,但沒有一個是全能的。我覺得關於對象 - 世界交互的設計大綱是最有用的一點信息,並且與我的問題最相關。 - – zyndor 2009-10-14 08:00:38