I'm creating a simple shmup from scratch. This is how my base Enemy class looks like:
class Enemy
{
public:
Enemy(int ntype, double nx, double ny, double nvx, double nvy):
type(ntype), x(nx), y(ny), vx(nvx), vy(nvy) {};
virtual ~Enemy() {};
void Move(){x+=vx;y+=vy;};
virtual void Logic()=0;
virtual void Draw();
bool IsDead(){return health<0;}
void ReduceHealth(int damage){health-=damage;}
SDL_Rect GetLoc(){return loc;}
protected:
int type;
int health;
double x, y;
double vx, vy;
SDL_Rect loc, source;
void GetVectorToPlayer(double &x, double &y);
double GetAngleToPlayer();
};
The Logic() function is the main function that defines the enemies' behaviours. It can influence both its movements and shooting patterns. For example, it may look like this:
double angle=GetAngleToPlayer();
if(globalFrameCounter%120==0) //will shoot every two seconds
for(int i=-3;i<=3;i+=1) //will shoot seven bullets in the player's direction
bulletManager->AddEnemyBullet(B_BULLET1, x, y, 5, angle+i); //bullet sprite, location, velocity and direction
Finally, all the enemies are created on the vector via the manager, like this (I have only one BasicEnemy subclass for now, so the function will be expanded int the future):
void EnemyManager::AddEnemy(int type, double x, double y, double vx, double vy)
{
enemies.push_back(std::unique_ptr<BasicEnemy>(new BasicEnemy(type, x, y, vx, vy)));
}
Now, my problem is, what if I want to have a lot of different types of enemy behaviours. In the current state, it would force me to write a separate subclass with a new Logic() function for every possible behaviour. That's obviously the wrong approach, since it would force me to create tens and tens of subclasses. I also don't want to use any scripting language like Lua, because I have no knowledge of them and it feels like using a sledgehammer to crack a nut.
So... is there an easier way that I'm not seeing?