0

サブクラスでスーパークラス変数を使用する方法と、それに変更を加える方法を理解するのを手伝ってください。SDL ライブラリを使用してスペース インベーダー 2D ゲームのクローンを作成しています。

まず、SDL_Rect から継承された Rectangle クラスを次のように作成します。重要でない部分は省略します。

//Rectangle.h 
namespace galaxy{
struct Rectangle : public SDL_Rect{
    Rectangle();
    Rectangle(int xx, int yy, int hh, int ww);
    Rectangel centeredRect(int width, int height) const
    bool overlaps(const Rectangle& other) const;
    };

}

長方形がこれでどの部分を演じているかを簡単に確認できるので、.cpp は省略します。皆さんを退屈させたくありません。

次に、ゲーム内のフィギュアのスーパークラスである Sprite クラスを作成します。

namespace galaxy{
class Sprite{
public:
virtual void draw() = 0;
virtual ~Sprite();

virtual void keyLeft(SDLKey k);
virtual void keyRight(SDLKey k);
......more buttons

protected:
Sprite(int x, int y, int h, int w);
private:
Rectangle rect;

Sprite (const Sprite&);
const Sprite& operator=(const Sprite&);
};
}

.cpp ファイルには、次のコードがあります

namespace galaxy{
Sprite::Sprite{int x, int y, int h , int w) : rect (x, y, h, w){}

Sprite::~Sprite(){}

const Rectangel& Sprite::getRect() const{
return rect;
}

void Sprite::keyLeft(SDLKey k){}
void Sprite::keyRight(SDLKey k){}
void Sprite::keyDown(SDLKey k){}
...more buttons
}

次に、問題がどこにあるのか、別のクラス Ship があります。ここでは、スーパークラスから keyLeft をオーバーロードし、座標に続く四角形を持ち、サブクラスの x と y を変更する必要がありますが、そうするときr.x++の下にある構造で; 関数内のように動作し、関数を終了するときに四角形 x への変更がクリアされます。Ship クラスで rect に到達しようとすると、r = getRect(); を介して rect を取得するときに、到達できないというエラーが発生します。r への変更は関数内のみですが、船は画面上で移動しません。

//Ship.h
    namespace galaxy {

    class Ship : public Sprite{
    public:





        void keyLeft(SDLKey k);
        void keyRight(SDLKey k);
        void keyDown(SDLKey k);
        void keyUp(SDLKey k);
        void space(SDLKey k);

        Ship(int x, int y, int hits);
    private:
        SDL_Surface* ship;
        int hits;

    };
}

//Ship.cpp
using namespace std;


namespace galaxy{
Rectangel r;



    Ship::Ship(int x, int y, int hits) : Sprite(x, y, NULL, NULL), hits(hits){
        ship = IMG_Load("Ship.png");
    }


     //Here is where my problem is.....
        void Ship::keyLeft(SDLKey k){ 
            std::cout << "Im here!\n";    
            std::cout << r.getX(); // outputs 250
            r.x--;
            std::cout << r.getX(); // outputs 251
        }
        void Ship::keyRight(SDLKey k){
        std::cout << "Im here!\n";
        }
        void Ship::keyDown(SDLKey k){
        std::cout << "Im here!\n";
        }
        void Ship::keyUp(SDLKey k){
        std::cout << "Im here!\n";
        }
        void Ship::space(SDLKey k){
        std::cout << "Im here!\n";

        }


    void Ship::draw(){
        r = getRect();
        SDL_BlitSurface(ship, NULL, sys.screen, &r);

    }

}

今、私はこれを次のようにやっています:

 #ifndef SHIP_H
#define SHIP_H
#include "Sprite.h"
#include <string>

namespace galaxy {

    class Ship : public Sprite{
    public:
        /*static Ship* getInstance(int x, int y, int hits);*/
        void draw();


        //virtual void perform() = 0;
        /*int getHits() const;*/
        int getX() const;
        int getY() const;
        const Rectangel& getRect() const;
        void keyLeft(SDLKey k);
        void keyRight(SDLKey k);
        void keyDown(SDLKey k);
        void keyUp(SDLKey k);
        void space(SDLKey k);
        //~Ship();
        //protected:
        Ship(int x, int y, int hits);
    private:
        SDL_Surface* ship;
        int hits;
        Rectangel rect;
    };
}

#endif


#include "Ship.h"
#include "Globals.h"
#include "Sprite.h"
#include <SDL_image.h>
#include <iostream>

using namespace std;


namespace galaxy{
Rectangel r;

    /*Ship* Ship::getInstance(int x, int y, int hits){
     return new Ship(x, y, hits);
     }*/

    Ship::Ship(int x, int y, int hits) : Sprite(x, y, NULL, NULL), hits(hits){
        ship = IMG_Load("Ship.png");
    }

        const Rectangel& Ship::getRect() const{ 
        return rect; 
    }

        void Ship::keyLeft(SDLKey k){ 
            std::cout << "Im here!\n";    
            rect.x--;
        }
        void Ship::keyRight(SDLKey k){
        std::cout << "Im here!\n";
        }
        void Ship::keyDown(SDLKey k){
        std::cout << "Im here!\n";
        }
        void Ship::keyUp(SDLKey k){
        std::cout << "Im here!\n";
        }
        void Ship::space(SDLKey k){
        std::cout << "Im here!\n";

        }

   /* int Ship::getHits() const{ 
        return hits; 
    }*/

    int Ship::getX() const{ 
        return r.getX();
    }

    int Ship::getY() const{ 
        return r.getY();
    }

    void Ship::draw(){
        r = getRect();
        SDL_BlitSurface(ship, NULL, sys.screen, &r);

    }

}

しかし、これは単なる回避策であるため、永遠に立ち往生することはありません。

4

2 に答える 2

2

rect基本クラスから直接アクセスしたい場合は、次のように保護された可視性Spriteを与える必要があります。rect

class Sprite
{
    [...]
protected:
    Rectangle rect;
    [...]
};
于 2013-07-18T20:15:02.310 に答える
2

次のようなことをすると:

Rectangel r;
...
r = getRect();

次に、元の長方形をr変数にコピーするだけです。変更すると、元のRectangelは変更されません。おそらく、簡単な修正のために、 setRect関数を Ship クラスに実装して、実際に変更されたデータを書き戻すことができます。

void Ship::setRect(const Rectangel& rr) { rect = rr; }
于 2013-07-18T20:05:48.943 に答える