RPG Classes

Started by
4 comments, last by ToohrVyk 15 years, 4 months ago
I am creating a text based RPG in C++. Right now I am trying to get the character classes down. The user will be able to create their own character. They will be able to select a race and based on their selected race, be able to select certain classes. I'm trying to use inheritance to accomplish this. My classes so far are the character class which has all the basic stats as members.

class Character
{
    protected:
        unsigned short str;
    //....
};


Then I have my races class which are responsible for setting the character stats depending on the race.

class Human : public Character
{
    public:
       // The constructor will set inherited members from character here.
       Human();
       ~Human();
};

//.....
// Then 3 more of the same classes but for dwarves, elves, and gnomes.


Now I have my profession classes which assigns the character their special abilities or spells depending upon their chosen profession. I have a class for every combination of race and profession possible. This is what I want to try to avoid, having so many classes to keep track of.

class Warrior_H : public Human
{
    public:
    // The constructor will set inherited members from the Human class here.
        Warrior_H();
        ~Warrior_H();
};

class Warrior_E : public Elf
{
    public:
    // The constructor will set inherited members from the Elf class here.
        Warrior_E();
        ~Warrior_E();
};

class Mage_H : public Human
{
    public:
        Mage_H();
        ~Mage_H();
};

// And the same for the rest of the remaining classes and their race.


Is there any way I can set up the classes so that there are not so many profession classes? Any help or advice would be great thanks. [Edited by - TheBinaryMan on December 24, 2008 2:45:08 AM]
Advertisement
you could have a Profession class which handles all the job stats, and have Warrior inherit from that. Character could have a protected member variable of Profession
Quote:Original post by Funkymunky
you could have a Profession class which handles all the job stats, and have Warrior inherit from that. Character could have a protected member variable of Profession


Not quite sure what you mean. Can you elaborate?
I think you're overusing inheritance and classes here. You're inheriting from a base class, but only to fill that base class with different values. That's not really the point of inheritance. How about just creating a Character instance for each character, and depending on it's type and profession, filling it with different data?

Character CreateCharacter(CharacterType type, Profession profession){   if(type == ELF)   {      if(profession == WOODCUTTER)         return Character(type, profession, 12, 15, 3, 4 /* bla-bla */);      else         // And so on   }   else if(type == HUMAN)   {      if(profession == WOODCUTTER)         return Character(type, profession, 14, 11, 4, 2 /* bla-bla */);      else         // And so on   }   // And so on}


It's a good idea to store this kind of data in a text file, so you can change it easily. This makes testing easier, because you don't need to rebuild your program every time you want to tweak a few values.

Now, the above code is example code to demonstrate how not to overuse classes for this. It's still not ideal, with all those if-else (or switch-case, if you prefer those) statements, but that can be reduced when you make it more data-driven.
Create-ivity - a game development blog Mouseover for more information.
Although your way is doable, its definitely not the most managable one.

You could go for the following approach aswell:

Base classes
class Character : public Creature // Creature being a lower order base class for example{  public:    Character(Race* race, Profession* profession);  private:    Race* m_Race = 0;    Profession* m_Profession = 0;}class Race{  protected:    Race(char* identifier);}class Profession{  protected:    Profession(char* identifier);}


Derived classes:
class Human : public Race{  public:    Human() : Race("Human") { }    }class Elf: public Race{  public:    Elf() : Race("Elf") { }    }class Warrior : public Profession{  public:    Warrior() : Profession("Warrior") { }}class Wizard : public Profession{  public:    Wizard () : Profession("Wizard") { }}


This makes it much more scalable, you can just derive the Race and/or Profession classes.

There are many ways here, but if you desire scalability I advise to take this approach or a similar one.

I hope this was helpful.

Regards,

Xeile
As a base approach, I would probably use:

enum races   = { HUMAN, ELF, DWARF, RACES };enum classes = { WARRIOR, WIZARD, THIEF, CLASSES };struct modifier { int str, dex, int, health, mana; };modifier race_traits[RACES] = {  {  0,  0,  0,  0,  0 }, // HUMAN  { -1, +1, +1, -2, +1 }, // ELF  { +2, +1, -3, +2, -2 }  // DWARF };modifier class_traits[CLASSES] = {  { +1, +1, -2, +1, -1 }, // WARRIOR  { -1, -1, +2, -2, +2 }, // WIZARD  { -1, +1, +1, -1,  0 }  // THIEF};


The point is that you can keep this data and use it regardless of whether you implement race/class configuration as a class hierarchy or as a single class. And code which you can keep using even when the rest of the code changes is good.

This topic is closed to new replies.

Advertisement