236
Подкласс песочница (Subclass Sandbox) —
Паттерны программирования игр
Имейте в виду
«Наследование» — не то слово, которое сейчас привет-
ствуется среди программистов. И одна из причин тому —
базовые классы склонны включать в себя все больше
и больше кода. И данный паттерн тому подтверждение.
Так как подклассы взаимодействуют со всем осталь-
ным кодом игры через базовый класс, он в итоге оказы-
вается связан со
всеми
подсистемами игры, с которыми
взаимодействует хотя бы один подкласс. Конечно, про-
изводные классы тоже тесно связаны со своим базовым
классом. Из-за паутины зависимостей практически не-
возможно, внося изменения, ничего не сломать — это
проблема хрупкого базового класса
.
С другой стороны, поскольку большая часть зависи-
мости сосредоточена в базовом классе, производные
классы отделены от остального мира. В идеале большая
часть поведения должна быть сосредоточена в этих под-
классах. Таким образом большинство кода является изо-
лированным, и его легче поддерживать.
И все же, если вы считаете, что паттерн превраща-
ет ваш код в огромную миску запутанного кода, рассмо-
трите разделение предоставляемых операций по раз-
ным классам, на которые базовый класс переложит
ответственность. Тут способен помочь паттерн Компо-
нент (Component) (с. 272).
Пример кода
Паттерн весьма прост, а потому нет смысла приводить
в пример много кода. Однако, несмотря на простоту, он
может быть полезным. Этот паттерн о
предназначении
,
а не о сложности реализации.
Начнем с базового класса
Superpower
:
class Superpower
{
public:
virtual ~Superpower() {}
Паттерны программирования игр
— Паттерны поведения
237
protected:
virtual void activate() = 0;
void move(double x, double y, double z)
{
// …
}
void playSound(SoundId sound)
{
// …
}
void spawnParticles(ParticleType type, int count)
{
// …
}
};
Метод
activate()
— это метод песочницы. Так как
он абстрактный и виртуальный, подклассы
должны
его
переопределять.
Другие защищенные методы
move()
,
playSound()
и
spawnParticles()
— предоставляемые операции.
Именно их будут вызывать подклассы в своей реализа-
ции
activate()
.
Мы не включили предоставляемые операции в при-
мер, но в настоящей игре там должен находиться на-
стоящий код. Эти методы — именно то место, где воз-
никает связь класса
Superpower
с другими системами
игры: метод
move()
может обращаться в код физиче-
ского движка,
playSound()
— звукового движка и так
далее. А поскольку все
реализовано
в базовом классе,
то зависимость как бы инкапсулирована в сам класс
Superpower
.
Итак, пора выпустить наших радиоактивных пауков
и создать им суперсилы. Вот одна из них:
class SkyLaunch : public Superpower
{
protected:
virtual void activate()
{
Do'stlaringiz bilan baham: |