2013-07-18 97 views
0

幫助我瞭解如何使用超變量的子類,並能夠進行更改,我使用SDL庫C++繼承子類修改變量

首先我有一個製作克隆太空入侵者2D遊戲是從SDL_Rect繼承這樣看我會留下不重要的部分出

//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,因爲它很容易看到rectangel在這一點,我不打什麼部位矩形類不想讓你們失望,

然後,我有一個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,但是當這樣做的時候, .X ++;在函數內部行爲,並且在退出函數時正在清除對矩形x的更改,當試圖在Ship類中達到矩形時,當通過r = getRect()獲取矩形時,我得到錯誤,但不可達。對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); 

    } 

} 

現在Im做此類似:

#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); 

    } 

} 

但是,這只是一種變通方法,使我不能永遠停留。

+0

得使用虛函數的多態性。 – IdeaHat

回答

2

如果你做這樣的事情:

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

然後你剛纔得到的原始矩形複製到[R變量,當你改變它,原來Rectangel不會改變。 也許爲了快速修復,你可以實現setRect函數到你的Ship類實際上能夠寫回修改後的數據。

void Ship::setRect(const Rectangel& rr) { rect = rr; } 
2

如果你想從Sprite基類到達rect直接,那麼你需要給像這樣的rect保護的可見性:

class Sprite 
{ 
    [...] 
protected: 
    Rectangle rect; 
    [...] 
}; 
+0

您好,請您詳細說明一下,該項目的代表是保持所有變量是私人的,有沒有其他方法來做到這一點,並保持私有? – MRK187

+0

我繼續前進,並保持我的矩形在超類精靈中受到保護,並且在Ship類中聲明瞭一個新的Rectangel, – MRK187

+0

對不起,我錯過了您的評論。那麼問題是你的類Ship繼承了Sprite。所以這是一個專門化,它將更多的邏輯和/或數據添加到基類中。因此它與基類緊密耦合。根據我的經驗,通常的做法是讓大多數成員受到保護,從而允許派生類直接訪問。它並沒有真正違反信息隱藏的概念。大多數成員只有在非常特殊的原因下才被宣佈爲私人,即使派生類也不應該直接觸及它們。 –