Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Proper Way to Design Multiple Enemy Types  (Read 4467 times)

0 Members and 1 Guest are viewing this topic.

XBigTK13X

  • Newbie
  • *
  • Posts: 3
    • View Profile
Proper Way to Design Multiple Enemy Types
« on: January 02, 2011, 11:19:48 pm »
I'm working on a simple game to learn the ins and outs of SFML and am currently running into the following issue.

I want to be able to update every enemy type from a single method. My initial thoughts on this are to have a layout similiar to the following:

[Enemy Class]
    -> Holds position,speed, and strength data
    -> All enemies are subclasses of this class

[FirstEnemyType Class]
    -> Parent class is Enemy
    -> Specialized Run() method to handle specific enemy type AI

[EnemyTracker Class (Singleton)]
    -> Contains a vector of Enemy
    -> UpdateEnemies method calls Enemy.Run on all enemies

[Main Function]
    -> Call EnemyTracker.Update() to update all enemies of all types of once

The issue I'm running into is that SFML cannot call Render on the Enemy type. I've tried solving this by having Enemy be derived from sf::Sprite, but I cannot find a way to have each derived enemy type have its own Image through this method. The other solution is to have each enemy type be derived from sf::Sprite, but then I cannot update as shown above because the Enemy type has no linkage to Drawable.

What is a good solution to this design problem? I want each enemy type to have individualized graphics but desire a single touch point for updating all enemies at once.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Proper Way to Design Multiple Enemy Types
« Reply #1 on: January 02, 2011, 11:30:22 pm »
Quote
The issue I'm running into is that SFML cannot call Render on the Enemy type

SFML classes can be drawn using window.Draw(stuff) because they are made to be used like this, but you don't have to do the exact same thing for your classes, just design your own system with your own functions.
Code: [Select]
class Enemy
{
public:

    void Draw(sf::RenderTarget& target)
    {
        // example
        target.Draw(mySprite);
    }
};

enemy.Draw(window);


By the way, if only the AI is different in Enemy subclasses, maybe you should limit inheritance to AI classes and keep a single Enemy class.
Code: [Select]
class Enemy
{
private:

    Behaviour* myBehaviour;
};

class Behaviour
{
public:

    virtual ~Behaviour();
    virtual void Update(...) = 0;
}

class StandardBehaviour : public Behaviour
{
    ...
};

class BossBehaviour : public Behaviour
{
    ...
};

Don't know if it fits your design, just a thought ;)
Laurent Gomila - SFML developer

XBigTK13X

  • Newbie
  • *
  • Posts: 3
    • View Profile
Proper Way to Design Multiple Enemy Types
« Reply #2 on: January 03, 2011, 11:23:14 am »
The issue is more along the following lines:

Code: [Select]

class EnemyTracker
{
 private:
    std::vector<Enemy> _enemies;
 public:
    DrawEnemies(sf::RenderTarget& target)
    {
        for(unsigned int i = 0;i<_enemies.size();i++)
        {
          target.Draw(_enemies[i]);
        }
    }
};

class Enemy
{
 public:
    int _health,_xPos,_yPos;
};

class FastEnemy: public Enemy,sf::Sprite
{
 private:
    int _moveSpeed;

};

class BigEnemy: public Enemy,sf::Sprite
{
 private:
    int _size;
};



This is an example of the type of setup I am trying to design. Basically, each type of enemy has its own Sprite and logic, but I want to have a generic parent type so that I don't need to make a new container every time I create a new type of enemy. How can this be done in C++ while having access to SFML?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Proper Way to Design Multiple Enemy Types
« Reply #3 on: January 03, 2011, 11:30:34 am »
I don't think you need to inherit from sf::Sprite.

Anyway, I gave you the solution in my previous post.
Code: [Select]
class EnemyTracker
{
 private:
    std::vector<Enemy> _enemies;
 public:
    DrawEnemies(sf::RenderTarget& target)
    {
        for(unsigned int i = 0;i<_enemies.size();i++)
        {
          _enemies[i].Draw(target);
        }
    }
};

class Enemy
{
 public:
    void Draw(sf::RenderTarget& target);
};
Laurent Gomila - SFML developer