Question

I am writing a game in C++ which has different enemy types. I have defined a base Enemy class and I also have derived classes enemy1, enemy2 etc. Now for updating these enemies in each iteration of the game, I want to have an array: EnemyArray with its elements pointing to the existing enemies so that I can make sure to update them all with their own version of update(), etc.

One way of doing this, would be to define separate arrays for each enemy type and that would be a clean way of solving the problem. However, I was wondering if the fact that these enemy classes are all derived from the same base class makes it possible to somehow have my EnemyArray as an array of Enemy's and do some modifications later.

Was it helpful?

Solution

You can specify base class with virtual function Update and derived classes overriding this function. Here is simple example:

class Enemy
{
public:
    // this is abstract function, but you can also add implementation 
    // as default behavior for derived classes
    virtual void Update() = 0; 
};

class Enemy1 : public Enemy
{
public:
    void Update()
    {
        // update Enemy
    }
}

class Enemy2 : public Enemy
{
    void Update()
    {
        // update Enemy
    }
}

Then create a vector of pointers to base class and fill with objects of specific type:

vector<Enemy*> enemies;
enemies.push_back(new Enemy1());
enemies.push_back(new Enemy2());

And your UpdateAll function can look like this:

void UpdateAll()
{
    for (int i = 0; i < enemies.size(); ++i)
    {
        enemies[i]->Update();
    }
}

Because you are using pointers, don't forget to release all allocated memory at the end of game.

OTHER TIPS

(I'm assuming C++)

std::vector holds its elements by value so if you store subclasses you are slicing the objects.

You can use the PImpl idiom to avoid this, you have a concrete Enemy class that holds a (unique) pointer to a concrete enemy an abstract IEnemy that holds the custom code.

class Enemy
{
  Point location;
  std::unique_ptr<IEnemy> pimpl;

  public:
    Enemy(IEnemy&& pimpl): pimpl(pimpl), location(){}

    void onTick(World w){
        pimpl->onTick(w);
    }
}

You can instead hold pointers in you vector std::vector<std::unique_ptr<Enemy>> so it doesn't hold them by value.

Licensed under: CC-BY-SA with attribution
scroll top