Sign in to follow this  

enemy system for shooter

This topic is 4710 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hey guys... i'm working on a 2d shooter, and i'm trying to figure how i can best implement my enemies. i was wondering, would it be better to have one generic Enemy class that works for everything, or having a separate class for each type of enemy? i think it would be easier to have a separate class for each type of enemy, but then again, i can't think of any difference between types of enemy that would justify making 'Enemy' an abstract class (other than the boss) thoughts?

Share this post


Link to post
Share on other sites
I would suggest googling for 'Inheritance' or read up on it somwhere, or whatnot. Inheritence lets you declare a base class, in your case Enemy, and put the things that are similar inside of it. Draw, Move, Think, position, etc. and then "inherit" other classes off of it, saying "This is a Ogre enemy, but its still an enemy" and you put the things specific to ogre in it, like Stench, Ugly (note: not real examples :)) and it will still have draw, move, think, inside of it. Theres more features of it, so i would suggest reading up on it, thats just the basics. Gladi could help give back to the gamedev community! :-D

Share this post


Link to post
Share on other sites
You don't necessarily need different enemy classes. One class is sufficient - you can (and should) use a data-driven design approach. Your enemies could for example have a micro-language that defines their behaviour (e.g. movement patterns or AI-behaviour).
Example:

// pattern command
struct Command {
int Id; // command id
int Param1; // generic parameter 1
int Param2; // generic parameter 2
};

// pattern entry - processed each game logic tick
struct PatternEntry {
int NumCommands; // Number of commands in this entry
Command * CommandList; // List of 'NumCommands' commands
PatternEntry * Next; // Linked list → pointer to next entry
};


const int CMD_IDLE = 0;
const int CMD_MOVE = 1;
const int CMD_SHOOT_UP = 2;
const int CMD_SHOOT_DIAG_LEFT = 3;
const int CMD_SHOOT_DIAG_RIGHT = 4;
const int CMD_SHOOT_DOWN = 5;
const int CMD_MOVE_TO_PLAYER = 6;
...

// simple commands processing
void Enemy::ProcessPattern() {

bool gotoNext = true;

// loop through all current commands
for (int i = 0; i < currentEntry->NumCommands; ++i) {

Command * command = currentEntry->CommandList[i];

switch (command->Id) {

// sample: IDLE waits Param2 ticks, Param1 is initially set to Param2 and is decremented each loop
case CMD_IDLE:

// decrement counter
if (command->Param1 > 0) {
--command->Param1;
gotoNext = false; // prevent from loading next entry
// set for-loop condition to false to leave it
i = 9999;
continue;
}

// idle counter elapsed → reset Param1
else {
command->Param1 = command->Param2;
}
break;

// move: Param1 is dx, Param2 is dy
case CMD_MOVE:

this->Move(command->Param1, command->Param2);
break;

// move to player: Param1 is velocity x, Param2 is velocity y
case CMD_MOVE_TO_PLAYER:
{
int x, y;
this->GetPlayerPosition(x, y);

if (x < this->positionX)
x = -1;
else if (x > this->positionX)
x = 1;
else x = 0;

if (y < this->positionY)
y = -1;
else if (y > this->positionY)
y = 1;
else y = 0;

this->Move(command->Param1 * x, command->Param2 * y);
}
break;
....
}
}

// move to next entry
if (gotoNext) {
currentEntry = currentEntry->Next;
}
}


Instead of a switch statement you could also use a std::map that maps command Ids to member functions. The good thing about these patterns is that you can define them in text files on disk, which you can modify and test without recompilation.
Plus you only need one pattern processor for all enemies and still create a unique behaviour for each enemy type.

HTH,
Pat

Share this post


Link to post
Share on other sites

This topic is 4710 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this