Jump to content
  • Advertisement
Sign in to follow this  
h2mprod

enemy system for shooter

This topic is 4959 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
Advertisement
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
Just think of different enemy types. Depending on the diversity you'll want to have an abstract or basic class.

Possible types:

o Boss
o following a path
o tracking the player
o Bullets
o grouping (flocks)

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;

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!