Game Programming Patterns / Паттерны программирования в играх: 3.2 Subclass Sandbox
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Цель XDMaik 04.05.14 в 09:08 |
|
|
Создать различные виды поведения, определяя подклассы, которые используют операции, предусмотренные их общей базового класса. XDMaik 04.05.14 в 09:09 Создание различных видов поведения путём определения подклассов, которые используют операции, предоставляемые их общим базовым классом. Mingun 13.05.14 в 16:02 |
||
|
Мотивация XDMaik 04.05.14 в 09:09 |
||
|
Каждый ребёнок мечтал стать супергероем, но, к сожалению, здесь, на Земле, недостаёт космических лучей. Mingun 13.05.14 в 16:04 |
||
|
Игры, позволяющие нам стать супергероем, являются наиболее близким приближением. Mingun 13.05.14 в 16:05 |
||
|
Поскольку наши игровые дизайнеры никогда не научатся говорить «нет», у нашего супергероя в игре планируются десятки, если не сотни, различных суперспособностей, которые могут заиметь игроки. Mingun 13.05.14 в 16:07 |
||
|
Наш план состоит в том, что мы будем иметь базовый класс суперспособности Superpower. Mingun 13.05.14 в 16:09 |
||
|
Затем мы создадим производные классы для каждой суперспособности. Mingun 13.05.14 в 16:09 |
||
|
Мы поделим дизайн-документ между нашей командой программистов и поручим им писать код. Mingun 13.05.14 в 16:11 |
||
|
Когда всё будет готово, мы будем иметь сотню классов суперспособностей. Mingun 13.05.14 в 16:11 |
||
|
Когда вы столкнётесь с большим количеством подклассов, как в этом примере, часто это будет значить, что подход, основанный на управлении данными, будет лучшим. Mingun 13.05.14 в 16:13 |
||
|
Вместо того, чтобы писать большое количество кода, определяющего различные способности, попробуйте найти способ определения их поведения через данные. Mingun 13.05.14 в 16:14 |
||
|
Шаблоны Объект типа, Байт-код и Интерпретатор — все они могут помочь. Mingun 13.05.14 в 16:16 |
||
|
Мы хотим, чтобы наш игрок погрузился в мир, изобилующий разнообразием. Mingun 13.05.14 в 16:17 |
||
|
О какой бы способности мы не мечтали, будучи ребёнком, мы хотим видеть её в игре. Mingun 13.05.14 в 16:18 |
||
|
Это означает, что подклассам суперспособностей необходимо делать практически всё: проигрывать звуки, порождать визуальные эффекты, взаимодействовать с ИИ, создавать и разрушать другие сущности игры и заморачиваться с физикой. Mingun 13.05.14 в 16:21 |
||
|
Не будет такого уголка в кодовой базе, который не был бы затронут этими подклассами. Mingun 13.05.14 в 16:21 |
||
|
Давайте предположим, что мы просто развязали руки нашей команде и поручили им написать классы суперспособностей. Mingun 13.05.14 в 16:23 |
||
|
Что произойдёт? Mingun 13.05.14 в 16:23 |
||
|
Появится много избыточного кода. Mingun 13.05.14 в 16:23 |
||
|
Хотя разные способности будут дико разнообразны, мы всё ещё можем ожидать значительного перекрытия функционала. Mingun 13.05.14 в 16:24 |
||
|
Многие из них будут порождать визуальные эффекты и проигрывать звуки одинаковым способом. Mingun 13.05.14 в 16:25 |
||
|
Замораживающий луч, тепловой луч и горчичный луч — все они довольно похожи, когда вы берётесь за них. Mingun 13.05.14 в 16:28 |
||
|
Если не координировать людей, реализующих их, будет много повторяющегося кода и впустую потраченных усилий. Mingun 13.05.14 в 16:29 |
||
|
Каждая часть игрового движка будет связана с этими классами. Mingun 13.05.14 в 16:29 |
||
|
Не зная ничего лучше, люди будут писать код, вызываемый из подсистем, которые никогда не были привязаны непосредственно к классам суперспособностей. Mingun 13.05.14 в 16:31 |
||
|
Если ваша система отрисовки организована несколькими аккуратными слоями, только один из которых предназначен для использования кодом вне графического движка, мы можем поспорить, что код суперспособностей проникнет в каждый из них. Mingun 13.05.14 в 16:33 |
||
|
Когда эти внешние системы необходимо будет изменить, появится неплохой шанс сломать код суперспособностей. Mingun 13.05.14 в 16:35 |
||
|
Как только мы заимеем различные классы суперспособностей, связанные между собой и различными частями игрового движка, неизбежно изменения в этих системах повлияют на классы способностей. Mingun 13.05.14 в 16:37 |
||
|
Это грустно, поскольку ваши программисты графики звука и пользовательского интерфейса вряд ли захотят так же быть программистами игрового процесса. Mingun 13.05.14 в 16:39 |
||
|
Будет трудно определить, каким инвариантам следуют все суперспособности. Mingun 13.05.14 в 16:40 |
||
|
Скажем, мы хотим быть уверенными в том, что все звуки, проигрываемые нашими способностями, правильно расставлены в очередь и приоретизированы. Mingun 13.05.14 в 16:42 |
||
|
У нас нет простого способа убедиться в этом, если все сто наших классов самостоятельно напрямую вызывают звуковой движок. Mingun 13.05.14 в 16:43 |
||
|
Что мы хотим — так это дать каждому программисту игрового процесса, реализующему суперспособность, набор «игрушек», с которым он мог бы играться. Mingun 13.05.14 в 16:46 |
||
|
Вы хотите, чтобы ваша способность проиграла звук — вот вам функция playSound(). Mingun 13.05.14 в 16:46 |
||
|
Хотите частиц? Mingun 13.05.14 в 16:47 |
||
|
Вот spawnParticles(). Мы обеспечим, чтобы эти операции покрыли все ваши нужды, так что вам не нужно будет включать случайные заголовочные файлы и совать свой нос в остальные части кодовой базы. Mingun 13.05.14 в 16:47 |
||
|
Мы сделаем это, сделав операции защищёнными методами в базовом классе Superpower. Mingun 13.05.14 в 16:51 |
||
|
Поместив их в базовый класс, мы дадим каждому подклассу способности прямой и простой доступ к ним. Mingun 13.05.14 в 16:53 |
||
|
Сделав их защищёнными (и, вероятно, невиртуальными), Mingun 13.05.14 в 16:53 |
||
|
мы тем самым сообщим, что они существуют специально для вызова из подклассов. Mingun 13.05.14 в 16:54 |
||
|
Как только у вас появятся эти игрушки, с которыми можно поиграть, нужно будет найти место их применения. Mingun 13.05.14 в 16:55 |
||
|
Для этого мы определим метод песочницы: абстрактный защищённый метод, которые подклассы должны будут реализовать. Mingun 13.05.14 в 16:56 |
||
|
С учётом всего вышесказанного, для реализации нового вида способности вам будет необходимо: Mingun 13.05.14 в 16:57 |
||
|
Создать подкласс класса Superpower. Mingun 13.05.14 в 16:58 |
||
|
Переопределить метод activate(). Mingun 13.05.14 в 16:58 |
||
|
Реализовать тело метода, вызывая защищённые методы, предоставляемые классом Superpower. Mingun 13.05.14 в 16:59 |
||
|
Теперь мы можем поправить нашу проблему избыточного кода путём предоставления таких высокоуровневых операций, какие только возможно предоставить. Mingun 13.05.14 в 17:00 |
||
|
Когда мы видим код, дублирующийся во множестве подклассов, мы всегда можем выделить его в новую операцию в классе Superpower и далее использовать её. Mingun 13.05.14 в 17:01 |
||
|
Мы обратили нашу проблему связности путём помещения этой связности в одно место. Mingun 13.05.14 в 17:04 |
