2013-12-22 139 views
4

C++(Arduino的包裝器)的問題:我正在寫,其具有連接一個LCD一個拍攝時間了遊戲一個Arduino -C++雙指針成員訪問

我有一個基類(Sprite),並從該另一類派生 - Alien,MissilePlayer。 Alien類的構造函數也有私有成員pMissile(指向Missile類的指針) - '對象內的對象'將是一種描述我認爲的方式。 [當Alien觸發一個導彈,它通過其自身的(X,Y)座標轉換爲導彈和導彈有它自己的移動從Alien開始的方法的座標]

我的問題是:我如何通過Alien對象訪問導彈的座標? 流線型代碼是下面,我也繪製的類的表示:

// Bass class - has a form/shape, x and y position 
class Sprite 
{ 
    public: 
    Sprite(unsigned char * const spacePtrIn, unsigned int xInit, unsigned int yInit); 
    virtual void Move() = 0; 
    void Render() { display.drawBitmap(x,y, spacePtr, 5, 6, BLACK); } 
    unsigned int getX() const { return x; } 
    unsigned int getY() const { return y; } 
    protected: 
    unsigned char *spacePtr; 
    unsigned int x, y; 
}; 


// Derived class "Missile", also a sprite and has a specific form/shape, and specific (x,y) derived from input sprite 
class Missile : public Sprite 
{ 
public: 
    Missile(): Sprite(&spaceMissile[0], 0, 0) {} 
    virtual void Move(); // its own method of moving 
}; 

// Derived class "Alien" - has a specific form/shape, and specific (x,y) position 
class Alien : public Sprite 
{ 
public: 
    Alien(); 
    virtual void Move(); // its own method of moving 
private: 
    Missile *pMissile; 
}; 

Alien::Alien(): Sprite(&spaceAlien[0], random(5, 75), random(4, 10)) 
{ 
    Missile MissileArray[MaxAmmoSize]; 
    pMissile = &MissileArray[0]; 
} 


void Alien::Move() 
{ 
    if(random(10) % 2 == 0) 
    x += 1; 
    if(random(10) % 3 == 0) 
    y += 1; 

    if((pMissile != NULL) && (random(10) == 1)) 
    { 
    pMissile->setCoord(x, y); 
    pMissile->Move(); // move the missile 
    pMissile++;  // move onto the next missile in the array 
    } 
    Render(); 
} 

/*****************************************************************************************/ 
Alien MONSTER; 
Player HERO; 
Alien *pMONSTER = &MONSTER; 

void loop() 
{ 
    display.clearDisplay(); 
    MONSTER.Move(); 
    HERO.Move(); 
    pMONSTER->getX(); // this is x location of MONSTER 
    **// how does pMONSTER access pMissile(x,y) within MONSTER.** 
    delay(100); 
    display.display(); 
} 

enter image description here

Embedded C++ Class interaction

+0

簡短的回答是「它不。」您可能需要在Alien中提供一個界面,讓您獲得pMissile的副本或轉發請求的界面。或者,將pMissile從外星人身上取下來,並且平等地對待其他實體。 –

+0

一個側面說明:作爲sprite的子類的外星人等聽起來不太好設計。外星人等*有*與他們相關的精靈(可能有幾個),但他們是遊戲對象。聽起來像組成會比繼承更好。那麼也可以更容易地弄清楚如何去做你所要求的。 – hyde

回答

1

的常用方法是吸氣函數添加到外來:

class Alien { 
public: 
    Missile* getMissile() { return pMissile; } 
} 

使用它:

Alien* a = getAlienFromSomewhere(); 
auto pMissile = a.GetMissile(); 
if (pMissile != NULL) { 
    x = pMissile->getX(); 
    y = pMissile->getY(); 
} 
0

我想你想通過外星人訪問你的導彈位置來測試你的英雄實體的碰撞,但是如果你需要保持你的導彈的軌道,你不應該用指向下一個導彈的指針「行走」如Alien::Move()所示。這樣做,您將失去數組開頭的參考。

恕我直言,我會做你的階級異己是這樣的:

// Bass class - has a form/shape, x and y position 
class Sprite 
{ 
    public: 
    Sprite(unsigned char * const spacePtrIn, unsigned int xInit, unsigned int yInit); 
    virtual void Move() = 0; 
    void Render() { display.drawBitmap(x,y, spacePtr, 5, 6, BLACK); } 
    unsigned int& getX() const { return x; } 
    unsigned int& getY() const { return y; } 
    protected: 
    unsigned char *spacePtr; 
    unsigned int x, y; 
}; 


// Derived class "Missile", also a sprite and has a specific form/shape, and specific (x,y) derived from input sprite 
class Missile : public Sprite 
{ 
public: 
    Missile(): Sprite(&spaceMissile[0], 0, 0) {} 
    virtual void Move(); // its own method of moving 
}; 

// Derived class "Alien" - has a specific form/shape, and specific (x,y) position 
class Alien : public Sprite 
{ 
public: 
    Alien(); 
    ~Alien(); // a destructor to cleanup your missiles - arduino have almost no memory to handle leaks ;-) 
    virtual void Move(); // its own method of moving 

    inline Missile& getMissile(unsigned char n) { return pMissile[n];   } 
    inline Missile& operator[](unsigned char n) { return getMissile(n);  } 
    inline unsigned int& getX(unsigned char n) { return getMissile(n).getX(); } 
    inline unsigned int& getY(unsigned char n) { return getMissile(n).getY(); } 

private: 
    Missile *pMissile; 
    // adding the code to handle the count 
    unsigned char missileCount; 
}; 

Alien::Alien(): 
    Sprite(&spaceAlien[0], random(5, 75), random(4, 10)), 
    missileCount(0) 
{ 
    // this way of allocation creates a local object that is destroyed by the end of this scope 
    //Missile MissileArray[MaxAmmoSize]; 
    //pMissile = &MissileArray[0]; 

    // so you should do somethin like this 
    pMissile = new Missile[MaxAmmoSize]; 
} 

Alien()::~Alien() 
{ 
    delete[] pMissile; 
} 

void Alien::Move() 
{ 
    if(random(10) % 2 == 0) 
    x += 1; 
    if(random(10) % 3 == 0) 
    y += 1; 

    if((pMissile != NULL) && (random(10) == 1)) 
    { 
    // my proposal to fire it up 
    Missile& missile = pMissile[missileCount]; 
    missile->setCoord(x, y); 
    missile->Move(); // move the missile 
    missileCount++; // move onto the next missile in the array 
    } 
    Render(); 
} 

使用這樣的代碼,你可以通過訪問您的導彈的位置:

MONSTER.getX(0) += 1; 
MONSTER[0].getY() +=1; 
MONSTER.getMissile(1).getX() = 10; 

有一些清晰度我還建議將getX()getY()方法重構爲x()y(),因爲它們正在返回對類內容的引用(並且這樣做,您還應該將您的xy成員到別的東西,或者你可以瘋狂與名稱衝突)。