2013-12-22 1 views
4

C++ (Arduino обертка) Вопрос: Я пишу Shoot Em Up игра на Arduino, который имеет ЖК-дисплей, подключенный -C++ двойной доступ член указатель

У меня есть базовый класс (Sprite), и от этого другого классы - Alien, Missile и Player. Конструктор класса Alien также имеет закрытый член pMissile (указатель на класс Missile) - «объект внутри объекта» был бы способом описать это, я думаю. [когда Alien запускает ракету, она проходит свой собственный (х, у) координаты ракеты, а ракета имеет свой собственный метод перемещения, начиная с 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 из Alien и просто относитесь к нему на равных с другими вашими сущностями. –

+0

Сторона примечания: инопланетянин и т. Д. Подклассы спрайта звучат не очень хорошо. Alien и т. Д. * Имеют * спрайт (возможно, несколько), связанный с ними, но это игровые объекты. Похоже, композиция была бы лучше, чем наследование. Тогда было бы легче также выяснить, как делать то, что вы просите. – 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(), так как они возвращают ссылки на содержимое класса (и при этом вы также должны переименовать свой x и y членов к чему-то другому, или вы можете сходить с ума от конфликтов имен).