248
Объект типа (Type Object) —
Паттерны программирования игр
Объект типа
(Type Object)
«Позволяет создавать более гибкие новые “классы”
через создание класса, каждый экземпляр которого
представляет новый объект типа».
Мотивация
Теперь мы создадим ролевую игру в стиле фэнтези. Нам
нужны орды злобных монстров, которые снуют вокруг
храброго героя и желают его растерзать. У монстров
есть набор различных характеристик: здоровье, параме-
тры атаки, графическое изображение, звук и так далее.
В нашем примере мы рассмотрим только первые две.
У каждого монстра в игровом мире есть показатель
текущего здоровья. Вначале он всегда заполнен, но каж-
дый раз, когда монстр получает ранение, значение пока-
зателя уменьшается. Также у монстра есть строка атаки,
то есть текст, который видит пользователь (пока не важ-
но как) каждый раз, когда монстр атакует героя.
Разработчики говорят, что все монстры будут при-
надлежать определенному
роду
: «дракон» или «тролль».
Каждый род описывает существующий в игре
вид
мон-
стра. При этом одновременно в подземелье могут нахо-
диться несколько монстров одного рода.
Род определяет начальный показатель здоровья мон-
стра — у драконов он выше, чем у троллей, чтоб их было
сложнее убить. Он же определяет содержание строки
атаки: все монстры одного рода атакуют с одинаковы-
ми сообщениями.
Глава 13
Паттерны программирования игр
— Паттерны поведения
249
Типичное решение ООП
Имея представление о разработке игр, мы запускаем
текстовый редактор и начинаем программировать. Со-
гласно проекту дракон — вид монстра, тролль — другой
вид, ну и так далее для остальных родов. Объектно-ори-
ентированное мышление приведет нас к созданию базо-
вого класса
Monster
:
class Monster
{
public:
virtual ~Monster() {}
virtual const char* getAttack() = 0;
protected:
Monster(int startingHealth)
:health_(startingHealth) {}
private:
int health_; // 9
};
Публичная функция
getAttack()
позволяет ответ-
ственному за сражение коду получить строку, появляю-
щуюся в момент нападения монстров. Каждый из про-
изводных классов рода будет переопределять ее, чтобы
разные монстры выводили разные сообщения.
Конструктор является защищенным и принимает
на вход начальное значение показателя здоровья. У нас
будут производные классы для каждого рода монстров,
где будут их собственные публичные конструкторы, ко-
торые вызывают базовый и передают ему начальное
значение здоровья, соответствующее роду. А теперь да-
вайте рассмотрим пару подклассов родов:
class Dragon : public Monster
{
public:
Dragon() : Monster(230) {}
Это так называемое от-
ношение «являться»
(is-a). В традиционном
представлении ООП
дракон «является» мон-
стром, а значит, модели-
руем мы его, делая класс
Dragon
дочерним клас-
сом
Monster
. Как мы
увидим позже, наследо-
вание — только один
из способов определить
концепцию подобных
отношений в коде.
Do'stlaringiz bilan baham: |