0

RPG要素のある迷路を中心としたシンプルな2Dゲームを書いています。主に、クラス設計、グラフ理論アルゴリズム、データ構造の使用、および 2D グラフィックスの使用を練習するための学習目的です。

プログラムの概要:

ゲーム自体はタイルベースです。現在、迷路を生成して画面に描画し、プレイヤーの移動と壁の衝突検出を可能にします。さらに、より大きな迷路の画面スクロールを処理できます。

とにかく、今私はマップの周りにオブジェクトを配置するオブジェクトの構築に取り組んでいます。リストの最初は金貨で、次にハートやアイテムなどです。継承とポリモーフィズムを実践する良い機会になると思いましたが、この種の設計に関する正式なトレーニングは受けていません。ヘッダーファイルは次のとおりです。

#ifndef MAP_OBJECT_H
#define MAP_OBJECT_H

#include "Common.h"
#include "Utility Functions.h"

const int TILE_SIZE = 80;

class MapObject
{
public:


    MapObject(unsigned int nClips, unsigned int r, unsigned int c, unsigned int cSize)     :
         sheet(0), clips(0), row(r), col(c), numClips(nClips), clipSize(cSize)
    {
        //For those of you who aren't familiar with sprite sheet usage, basically this
        // handles which part of the sprite sheet your on, so it will draw the correct sprite to the screen
        if(numClips > 0) clips = new SDL_Rect[numClips];
        box.h = clipSize;
        box.w = clipSize;
    }

    virtual ~MapObject()  //NOt sure if this is right.  All the derived classes will
                          // behave the same upon deletion, since the only resource 
                          //  that got allocated was for the box SDL_rect
    {
        if(clips) delete[] clips;
    }


    void initBox(int modX, int modY);
    //I think each object will draw a little different, so I made it virtual
    virtual void draw() = 0;
    //Same with interaction--although I'm not sure how my player class is going to be able to handle this yet
    virtual void interact() = 0;

     SDL_Rect getBox() const;

 private:
    SDL_Surface*  sheet;
    SDL_Rect      box;
    SDL_Rect*     clips;
    unsigned int  row, col;
    unsigned int  numClips;
    unsigned int  clipSize;

     MapObject() {}  //Made this private because I want the memory to be allocated, and 
                     // numClips needs to be initialized for that to happen, so 
                     //basically I'm forcing the user to use the constructor with parameters
};


class Coin : public MapObject
{
    enum  CoinFace  //This represents all the different coin facings in the sprite 
                     //sheet, so that is can animate.  Used in the draw function.
    {
        FRONT,
        TURN1,
        TURN2,
        TURN3,
        USED
    };

    CoinFace  active;

public:
    virtual void draw(SDL_Surface* destination);
    virtual void interact();
};

#endif //MAP_OBJECTS

私の最大の質問は一般的なものです。これは私のデザインの良いスタートですか? 彼らの明白な問題はありますか?OOD の原則/慣例の誤用?

そのように仮想デストラクタを定義すると、すべての派生クラスがそれを使用できるようになりますか? または、派生クラスごとに定義する必要がありますか?

これは大変なことだと思います。助けていただければ幸いです。私は本当にOODとポリモーフィズムの使用方法を理解しようとしているので、何人かのプロからの助けが信じられないほど役に立ちます.

再度、感謝します。

EDIT:私が持っている大きな質問は、派生クラスのプライベートデータメンバーを変更できるようになるという問題です。これを行う必要がある場合、クラスの設計が悪いと聞きましたが、適切なインターフェイスを作成する方法がわかりません。

4

1 に答える 1

6

質問の一部は意見の問題に依存しています。それにもかかわらず:

  1. ここで言えることは、あなたのアプローチはうまくいくということだけです。Coin のコンストラクタを定義することを忘れないでください。
  2. 仮想デストラクタの全体的な目的は、基本クラス型のポインタしかない場合に適切なデストラクタを呼び出すことです。さらに、派生デストラクタは、基本デストラクタが自動的に呼び出される前に実行されます。明示的に呼び出す必要はありません。この場合、 a が指すコインは、、、の順にMapObject*正しく破壊されます。delete~Coin()~MapObject()
  3. この質問は、適切なインターフェイスの構築に関する議論に簡単に変わる可能性がありますが、いくつかの解決策を次に示します。
    • コンストラクターを介してプライベート メンバーを定義し、他のクラスによって変更されないようにします。
    • protectedの代わりに基底クラスでメンバーを作成しprivateます。これは、ここでやりたいことに対するより簡単な解決策かもしれません。
    • などのプライベート メンバー タイプのセッターを作成しますsetActive(CoinFace)。これらの関数は、オブジェクト全体の一貫性を損なう属性の無効な定義を防止するなど、ニーズに合わせて調整できます。前のソリューションと同様に、これらのセッターを保護して、派生クラスのみがアクセスできるようにすることができます。
    • クラスを別のクラスの afriendにします (A と呼びます)。A のインスタンスは、そのクラスのオブジェクトを取得し、そのすべてのプライベート メンバーにアクセスできます。
于 2012-08-05T17:13:48.373 に答える