Я создаю небольшие компоненты, которые будут использоваться для RPG позже, однако мой опыт в этом масштабе проекта очень ограничен, поэтому я решил построить их независимо друг от друга. Эта часть будет посвящена созданию и обработке персонажа.
Таким образом, у меня есть следующий вектор, который хранит указатели класса Gender. Я знаю, что будет только четыре человека, Неизвестный (для ошибок), Мужской, Женский и Нойтер.
std::vector<Gender*> mGenders;
Однако для некоторых других векторов я не знаю точной суммы.
std::vector<BClass*> mBClasses;
У меня есть Существа, у которых есть mGenderID, а также mBClassID. У меня есть game.h, который инициализирует все гендерные группы и базовые классы (среди многих других). Скажем, у меня есть
Creature* mPC = new Creature ("Name", GenderID, BClassID);
Должен ли я тогда
Gender* Game::getGenderByID(int id) {
for (std::vector<Gender*>::iterator it = mGenders.begin(); it != mGenders.end(); ++i) {
if ((*it)->getID() == id) return (*it)
}
}
И используйте его следующим образом
std::cout << "Your name is " << mPC->getName() << ". Your gender is " << getCreatureByID(mPC->getGenderID())->getName();
Поэтому мой вопрос заключается в том, что это хороший способ структурирования кода? Представьте себе игру с бесконечным движком, ворота Балдура или так. Предположительно, он должен работать для большинства, даже если я буду заниматься Skyrim или GTA-подобной игрой.
Наконец, насколько легко было бы это сделать для С#? Поскольку я знаю C++ лучше, чем С#, я думал, что сначала дам ему C++, чтобы структура была правильной и работала с чем-то, что можно использовать в проектах более крупного масштаба.
Изменение: было бы лучше сразу сохранить пол * в классе Существо? И нет идентификатора существа?
Edit2:
class Gender {
public:
Gender::Gender(int id, std::string name, std::string desc, int coeBonus, int strBonus, int agiBonus, int attBonus, int intBonus, int chaBonus);
~Gender();
int getID () const;
std::string getName () const;
std::string getDesc () const;
int getStrBonus () const;
int getAgiBonus () const;
int getAttBonus () const;
int getIntBonus () const;
int getChaBonus () const;
int getCoeBonus () const;
private:
int mID;
std::string mName;
std::string mDesc;
int mStrBonus;
int mAgiBonus;
int mAttBonus;
int mIntBonus;
int mChaBonus;
int mCoeBonus;
};
Определение gender.h
заранее спасибо
С большой помощью от gamedev я теперь доволен тем, сколько кода структурировано.
Вместо хранения целых чисел, содержащих идентификаторы полов, рас и т.д. Теперь я сохраняю указатель на них. Отображение устаревших getGenderByID (int id).
В настоящее время я работаю над системой buff/debuff (effect) вместо того, чтобы иметь все различные бонусные переменные.
Эти изменения должны сделать код достаточно хорошим для практики!
Gender::Gender(int id, std::string name, std::string desc, int coeBonus, int strBonus, int agiBonus, int attBonus, int intBonus, int chaBonus);
в
Gender(int id, std::string name, std::string desc, Effect* effect);
В настоящее время работает над классом Effect, поэтому не могу много рассказать об этом.
Спасибо за комментарии.
std::vector<Gender*> mGenders;
Я не вижу достаточной причины хранить указатели в вашем векторе. Почему бы просто не иметь std::vector<Gender>
?
Во всяком случае, кажется странной идеей иметь контейнер " Gender
. Как вы говорите, у вас есть 4 возможных пола, которые вы затем сохраняете в этом векторе. Таким образом, вектор всегда имеет размер 4, и вы никогда ничего не удаляете из него или ничего не добавляете к нему? И каждый элемент в принципе просто представляет собой возможный ген, который может иметь существо? То есть вы перечисляете возможные гендерные группы. Похоже, вы хотите enum
(или enum class
) вместо этого!
enum class gender {
unknown,
male,
female,
neuter
};
Тогда нет необходимости возиться с уродливыми идентификаторами, которые на самом деле ничего не значат (по крайней мере, сейчас они скрыты за перечислением).
Тогда вы можете создать такое существо:
Creature mPC("Name", gender::male);
Если вы хотите распечатать их, вам понадобится какое-то сопоставление из значения перечисления в строки. Один из способов сделать это - просто иметь функцию, которая switch
es в аргументе gender
и возвращает соответствующую строку. Кроме того, вы можете создать std::map
следующим образом:
std::map<gender, std::string> genderNames =
{{gender::unknown, "Unknown"}, /* ... */};
Затем вы можете напечатать определенный ген существ, просто сделав:
std::cout << genderNames[mPC.getGender()];
У вас, похоже, есть нездоровая тенденция хотеть использовать динамическое распределение для ваших объектов. Не делайте этого, если это необходимо, и когда это необходимо, предпочитайте интеллектуальные указатели над необработанными указателями.
Gender
структура, вы можете рассмотреть возможность использования enum или enum class.