Composition/Inhertiance/Interface design wall

Started by
1 comment, last by Zahlman 15 years, 9 months ago
I'll throw the pseudocode up (language-agnostic)

IPerson //interface
{
   walk (int speed)
   dodge (enum direction)
   fight (bool yesorno)
   health ( )
}

Pedestrian : IPerson
{
   //of course methods above to be implemented here  
}

GoodGuy : IPerson
{
   //of course methods above to be implemented here

   morality (unsigned int amount)
   fightskills (enum skills, bool yesorno)
}

Hero : GoodGuy
{
   //of course methods above to be implemented here

   specialabilities( ... )
}

Hercules
{
   private:
      Hero yesIAm

   //of course methods above to be implemented here through access methods
}

Hero[] army = new Hero[100]
Hercules hercules = new Hercules

foreach (Person ingame in persons)
{
   print [ingame.health] // health method returns int from -1 and 101
}
Now I'm pretty sure that Hercules won't print its health using that foreach loop. And the reason for structuring the classes this way is because Hercules is a specific type of GoodGuy. There won't be more than one of him in the game at any time. So I'm wondering if I can get Hercules to be treated the same as a Hero. Basically have them both recognized to the program as IPerson.

Beginner in Game Development?  Read here. And read here.

 

Advertisement
"has-a" and "is-a". All you need to know.
Hercules "is-a" hero. Hercules does not "has-a" hero.

Or, better yet, since there is only one of them, make your "hero" class configurable so that all heroes fall under the hero class and are just specific instances of them with unique scripts.

Think about an RTS style game. Theoretically, any 'unit' could be defined by the unit class and just made configurable as to the sounds/images/scripts. So your 'Hercules' unit, which has the same underlying structure as the simple peon, is only instantiated once (and you could use a contract model to enforce this). That is the only difference.

If I were designing a game, I would probably use a component based design. BUT, if I were doing it your way, I would probably do something like this:

class Unit:   attribute my_sounds : sounds;    attribute graphics my_images : graphics;   attribute my_script : script;   Unit(sound_file, image_file, script_file):      my_sounds = loud_sounds(sound_file);       my_images = load_gfx(image_file);      my_script = load_script(script_file);   run(time_step):      execute(my_script, {:sounds=>my_sounds, :images=>my_images}, time_step);


This way, whether it is Hercules or a Peon, the structure doesn't change. Only the script, sounds, and graphics do.
Hercules: IPerson {  Hero impl  walk (int speed): impl.walk(speed)  dodge (enum direction): impl.dodge(direction)  fight (bool yesorno): impl.fight(yesorno)  health ( ): impl.health()}


Delegation. (The fact that IPerson is a real interface class should protect you from "multiple copies of base" type problems.)

The exact nuances of "getting Hercules to be treated the same as a Hero" aren't, in fact, "language agnostic", though. Consider that in Python, duck typing means that you often don't even bother specifying inheritance hierarchies or interfaces.

This topic is closed to new replies.

Advertisement