サブクラスでスーパークラス変数を使用する方法と、それに変更を加える方法を理解するのを手伝ってください。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);
}
}
しかし、これは単なる回避策であるため、永遠に立ち往生することはありません。