1
\$\begingroup\$

So I was just looking through an old game I had made for android, and was second guessing how I was sub-classing enemy for each particular enemy in my game. My enemy class had all kinds of properties, like sprite speed size and different bools that related to the state of the enemy...etc. But then for each enemy in the game I created a sub-class from enemy, and all I did was set all those properties to a specific value. Something like this:

public class Ninja extends Enemy
{
     public Ninja(Vector2 pos)
     {
         super(pos);
         this.speed = 10;
         this.sprite = Content.Ninja;
         this.size = spriteSize.Medium;
         this.hitPoints = 200;
         //..etc
     }
}

That was basically the whole class. Looking back it seems like a waste of making a class at all, it left me with nothing else to change about that enemy, but just a convenient way to declare them. Is this common practice? I suppose it is nice to have all these stats grouped into 1 place, but it seems like a small amount of information to have for a whole class, maybe I'm just over-thinking this. Does anyone else ever do similar things in their games? Maybe it would be better to just make a static method somewhere that generates a Enemy with these stats called like CreateNinja, and save myself the clutter of having a whole class for it. What do you guys think?

\$\endgroup\$
  • 2
    \$\begingroup\$ You want to be more worried about how early design decisions will affect your ability to create new enemy types and customize them later, and not so much about how it seems like a lot of overhead right now. \$\endgroup\$ – Patrick Hughes Nov 15 '13 at 3:44
  • 1
    \$\begingroup\$ This is pretty common. Instead of writing it as a class, write it as data (eg. text file) and viola, you have a "data driven" architecture. \$\endgroup\$ – ashes999 Nov 15 '13 at 4:27
  • 1
    \$\begingroup\$ The data-driven approach is much better, unless there's a compelling reason that a new enemy type needs to be a different class, just have an Enemy class. Assign parameters such as sprite and name to that class. That way you can configure all your enemies in a config file and you don't have to rebuild your whole project because you tweaked an enemy's parameters or added a new enemy. \$\endgroup\$ – Foo Barrigno Nov 15 '13 at 12:08
2
\$\begingroup\$

Your idea of using a static method is probably the way to go. Give Enemy a constructor with all the values as parameters, then use static methods to make it easy to call it.

Generally, you extend a class so you can override its methods. Suppose Enemy has a goToPoint method that moves the object in a straight line at a constant speed. You want a Ninja to disappear from its current position and reappear at the appropriate point. In this case you want to override this method, and creating a Ninja class that extends Enemy makes sense.

Another point: it might be a good idea to have an Enemy object contain a Ninja object. The Enemy class would be written to use the Ninja (it would have to extend or implement something else, maybe a "Person" interface) to handle a lot of its methods (movement, taking damage, doing damage, etc.). This lets your Enemy object change it's essential nature without the rest of your program having to worry about it. Your ninja is killed? Replace the Ninja object with the DeadBody object. Your ninja finds a full suit of Medieval Eurpopean armor? (And likes it?) Replace the Ninja object with the Knight object. And you could have a Friend class that also holds a "Person" instance, so you could stuff a Ninja, Knight, or DeadBody into that as and when needed.

OOP can do an awful lot for you, but there's a big problem: it's counterintuitive. Use inheritance in the obvious way and it will tie you into knots. Put a little twist on it and it can dramatically simplify your code and put all the code that does one job in one place where it neither troubles nor is troubled by the rest of your program.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.