10

SDLで簡単なゲームを書いています。ゲームで使用するスプライト用に構築しているクラス階層があります。基本クラスは Sprite で、コリジョン ボックスとスプライト シートのデータ抽象化が含まれています。そのすぐ下には、Character と MapObject という 2 つの抽象クラスがあります。

私は現在、Character から派生した Player クラスを実装しています (敵と NPC も抽象 Character クラスから派生します)。

とにかく、うまくいけばそれは理にかなっている。私の問題はこれです:

エンジンでプレーヤー クラスを使用しようとすると、Sprite 関数にアクセスできません。

次のエラーが表示されます。

'Sprite' is not an accessible base of 'Player'

ヘッダー ファイルは次のとおりです。

Sprite.h:

class Sprite{
public:
    virtual ~Sprite() = 0;  //I want this to be an abstract class and yes this is defined in the cpp

    //Initialization functions - MUST be called before anything else in the class can be used.
    void setupCollider(int xo, int yo, int ho, int wo);
    void setupSheet(SDL_Surface* dest, std::string file, int numClips, int ac, int _res, int sr);

    //SpriteSheet functions
    void setActiveClip(int a);
    int getActiveClip() const;
    void draw() const;
    int getResolution() const;
    SDL_Surface* getDest();


    //Collider functions
    void updateCollider();
    SDL_Rect box() const;
    bool collision(SDL_Rect other) const;

    //Access and Modify coordinates of the sprite
    void setLoc(int x, int y) { _x = x; _y = y; }
    int getX() const { return _x; }
    int getY() const { return _y; }

private:
    struct Collider{
        SDL_Rect  _box;
        int       x_offset,
                  y_offset;
    };

    struct SpriteSheet{
        SDL_Surface*     destination;
        SDL_Surface*    sheet;
        SDL_Rect*       clips;
        int             _numClips;
        int             active;
        int             res;
        int             sheetrows;
    };


    Collider     collisionAttributes;
    SpriteSheet  spriteSheetAttributes;
    int          _x, _y;

};

Character.h:

class Character : public Sprite{
public:
    virtual void move(Direction direction_input, const TileMap& currentlevel) = 0;
    virtual void animate() = 0;

    virtual void setAttributes( int h, int sp, int ad, int d, int m, int md, int l, std::string n){
        hearts = h; speed = sp; attackdamage = ad;
        defense = d; magicdamage = m; magicdefense = md;
        level = l; name = n;
    }

    bool isDead() const{
        return hearts == 0;
    }

    void heal(int heartsup){
        hearts += heartsup;
    }

    void dealDamage(int heartsDown){
        hearts -= heartsDown;
    }


protected:

    int hearts;
    int speed;
    int attackdamage;
    int defense;
    int magicdamage;
    int magicdefense;
    int level;
    std::string name;

};

Player.h:

//Not fully finished yet, but should work for the purposes of this question
class Player : protected Character{
public:
    ~Player(){
        if(heart) SDL_FreeSurface(heart);
    }
    static const int HEART_WIDTH;

    void move(Direction direction_input, const TileMap& currentlevel);
    void animate();

    void updateCamera(TileMap& currLevel);


 private:

    SDL_Surface* heart;

    enum ClipFace
    {
        UP1,
        UP2,
        DOWN1,
        DOWN2,
        LEFT1,
        LEFT2,
        RIGHT1,
        RIGHT2
    };

    static const std::string HEART;
    static const int HEART_RES;

};

プレーヤーでスプライトからセットアップ関数を呼び出そうとすると、エンジンで最初のエラーが発生します。最初のエラーは次のとおりです。

player.setLoc(levels[0].startX(), levels[0].startY());

ありとあらゆる助けをいただければ幸いです。

[解決済み] 編集: コメントの代替ソリューション: キャラクター クラスは Sprite クラスから何も継承していないため、技術的に派生させる必要はありませんでした。Character が Sprite を継承する代わりに、Player が Sprite と Character の両方を継承するようにしましたが、これも機能しました。どちらがより良いデザインなのかはわかりません。

4

3 に答える 3

14

私はあなたが変わる必要があると思います

class Player : protected Character{

class Player : public Character{

そうすれば、プログラムの任意の場所に作成された のインスタンスから、オブジェクトのCharacterおよびSpriteの関数にアクセスできます。PlayerPlayer

aPlayerができることは何でもできるべきである場合Characterpublic継承は理にかなっています。またはオブジェクトPlayerで自由にアクセスできるものを に隠す理由はありません。CharacterSprite

于 2012-08-12T01:28:24.470 に答える
1

public「is-a」関係を表すには、常に継承を使用してください。のように聞こえるので、継承は ではなく である必要がPlayerあります。Characterpublicprotected

protected継承とprivate継承は「has-a」に似ています (ほとんどの場合、メンバー サブオブジェクトはその関係を処理する簡単な方法です)。

于 2012-08-12T01:28:46.857 に答える
0

Characterは保護された基本クラスであるため、へのアクセスを制限していると思いますSprite

于 2012-08-12T01:27:51.430 に答える