Какие шаблоны проектирования программирования полезны при разработке игр? [закрыто]

129

У меня есть несколько книг по шаблонам проектирования, и я прочитал несколько статей, но не могу интуитивно понять, какие шаблоны проектирования программирования будут полезны при разработке игр.

Например, у меня есть книга под названием ActionScript 3 с шаблонами проектирования, в которой подробно описаны некоторые шаблоны проектирования, такие как Model View Controller, Singleton, Factory, Command и т. Д.

Как кто-то новичок в этом, я не могу понять, какой из них будет полезен, или на самом деле, если какой-то из этих шаблонов дизайна я должен изучать и пытаться использовать. Возможно, есть другие, более специфичные для игрового программирования шаблоны проектирования, о которых я даже не подозреваю?

Если у вас есть опыт использования определенного шаблона проектирования в разработке игр, я бы хотел это услышать. Рассуждение о том, почему оно использовалось, примеры кода или онлайн-ресурсы также будут очень полезны, если они у вас есть. В данный момент меня больше всего интересуют реализации ActionScript 3 и C ++, но я определенно могу извлечь пользу из опыта и примеров из любого языка.

Спасибо!

jcurrie33
источник
«Возможно, есть другие, более специфичные для игрового программирования шаблоны проектирования, о которых я даже не подозреваю?» - нет, эти шаблоны являются общими и больше применяются для расширения возможностей языка, который вы используете. Они не имеют ничего общего с предметом вашего заявления.
Kylotan
3
@Kylotan С моей ограниченной точки зрения кажется, что, поскольку каждый шаблон проектирования предназначен для эффективного решения конкретной проблемы, по своей природе некоторые шаблоны проектирования будут более полезными, чем другие, учитывая конкретный набор проблем, а именно в этом случае, эти проблемы уникальны для разработки игр. Конечно, есть некоторые руководящие принципы, или, исходя из вашего опыта, конкретные шаблоны проектирования, которые вы используете чаще других?
jcurrie33
Прежде чем кто-нибудь уйдет и выучит 1000 различных шаблонов дизайна, пожалуйста, прочитайте это и это
BlueRaja - Дэнни Пфлугхофт
@ BlueRaja-DannyPflughoeft Secon ссылка недействительна. Можете ли вы отправить его еще раз
Emadpres

Ответы:

163

Теперь для менее легкомысленного ответа, с некоторыми предложениями. Не принимайте их как рекомендации по реализации, а скорее как примеры возможного использования.

  • Builder: настройка компонента на основе компонентов по одному компоненту за раз на основе данных
  • Фабричный метод: создайте NPC или виджеты GUI на основе строки, прочитанной из файла
  • Прототип: сохраните один универсальный символ 'Эльф' с начальными свойствами и создайте экземпляры Эльфа, клонируя его.
  • Синглтон: это пространство намеренно оставлено пустым.
  • Адаптер: включите дополнительную стороннюю библиотеку, обернув ее в слой, который выглядит как существующий код. Очень полезно с DLL.
  • Составной: создайте граф сцены из визуализируемых объектов или создайте графический интерфейс из дерева виджетов.
  • Фасад: упростите сложные сторонние библиотеки, предоставив более простой интерфейс, чтобы сделать вашу жизнь проще в будущем.
  • Flyweight: хранить общие аспекты NPC (например, модели, текстуры, анимации) отдельно от отдельных аспектов (например, положение, здоровье) в основном прозрачным способом
  • Прокси: создайте на клиенте небольшие классы, представляющие более крупные и сложные классы на сервере, и пересылайте запросы по сети.
  • Цепочка ответственности: обрабатывать ввод как цепочку обработчиков, например. глобальные клавиши (например, для снимков экрана), затем GUI (например, в случае, если текстовое поле находится в фокусе или меню вверх), затем игра (например, для перемещения персонажа)
  • Команда: инкапсулировать функциональность игры в виде команд, которые можно вводить в консоль, сохранять и воспроизводить, или даже создавать сценарии для помощи в тестировании игры.
  • Посредник: реализуйте игровые сущности в виде небольшого класса посредника, который работает с различными компонентами (например, чтение из компонента здоровья для передачи данных в компонент AI)
  • Наблюдатель: иметь визуализируемое представление персонажа, слушающего события из логического представления, чтобы при необходимости изменять визуальное представление, при этом игровой логике не нужно ничего знать о рендеринге кода
  • State: хранить NPC AI как одно из нескольких состояний, например. Атакующий, блуждающий, убегающий. У каждого может быть свой собственный метод update () и любые другие необходимые ему данные (например, хранение символа, из которого он атакует или бежит, области, в которой он блуждает, и т. Д.)
  • Стратегия: переключаться между различными эвристиками для поиска A *, в зависимости от того, в какой местности вы находитесь, или, возможно, даже использовать одну и ту же среду A * для выполнения поиска пути и более общего планирования
  • Шаблонный метод: настройте общую «боевую» подпрограмму с различными функциями ловушек для обработки каждого шага, например. уменьшать боеприпасы, рассчитывать вероятность попадания, разрешать попадания или пропуски, рассчитывать урон, и каждый тип навыка атаки будет реализовывать методы по-своему

Некоторые модели не учтены из-за недостатка вдохновения.

Kylotan
источник
Очень поучительная дискуссия о синглетонах может быть найдена здесь: misko.hevery.com/2008/08/25/root-cause-of-singletons
Эндрю Ван
+1 за образец стратегии. Я использовал его для точной цели, указанной выше (подключая различные A * эвристики).
Майк Штробель
1
спасибо за этот ответ, они звучат больше как шаблон дизайна, чем обычный "синглтон", который я слышу везде ...
Jokoon
Большой список примеров. Несмотря на хроническое злоупотребление шаблоном синглтона (скрытое глобальное состояние), есть законное использование: когда он представляет ресурс, у которого вы фактически имеете (или хотите) только один. Это может быть что-то вроде обертывания оборудования (например, клавиатуры / мыши) или обертывания библиотеки, которая не является повторно входящей (это случается, и не все языки имеют магические ключевые слова синхронизации).
charstar
11
Я бы по-прежнему не использовал синглтоны для аппаратных ресурсов - предметы, которые, как вы думаете, у вас когда-либо будет, будут иметь тенденцию к умножению позже, как это делали видеокарты и мониторы в течение многих лет. Аналогично, в некоторых API вам нужно прочитать 2 джойстика, чтобы понять 1 геймпад. Поэтому я бы сказал, что если вам нужно только что-то, просто создайте экземпляр, не устанавливайте произвольные ограничения, которые, вероятно, не нужны.
Kylotan
59

Я написал книгу именно на эту тему: шаблоны программирования игр . Главы, которые там есть, могут быть полезны для вас.

muntiful
источник
2
+1 Я надеялся, что кто-то связался с этим, и я вижу, что автор имеет! Описание шаблона компонента было довольно полезным, и мне нравится, что вы пытаетесь использовать полные примеры кода для демонстрации.
CodexArcanum
2
Да, я помню, как читал вашу ссылку несколько лет назад. Вы должны закончить эти статьи!
onedayitwillmake
2
Теперь книга закончена :)
Душан
1
Удивительный ресурс, который помог мне перевести мои знания программирования в программирование для игр. Спасибо, что написали это!
Это объяснение шаблонов программирования игры фактически помогло мне понять шаблоны проектирования таким способом, которого не было ни в одной книге по шаблонам проектирования программного обеспечения! Отчасти это сила разработки игр (конкретные примеры на языке, который говорит со мной и позволяет мне улучшить мою разработку в целом), но в большей степени потому, что написание так превосходно.
Kzqai
19

Брэндон Айх хорошо понимал, что паттерны в Coders at Work - это хаки и обходные пути: [паттерны] показывают какой-то дефект в языке. Эти шаблоны не являются бесплатными. Там нет бесплатного обеда. Таким образом, мы должны искать эволюцию в языке, который добавляет правильные моменты.

Как программисты игр, а не дизайнеры компиляторов, мы редко получаем возможность развивать языки, которые мы используем, но мы можем научиться развивать наш собственный стиль, чтобы лучше соответствовать нашему языку и требованиям. Шаблоны - это часть этого, но не использование шаблонов - это еще одна часть, тем более что, как говорит Брэндон, шаблоны редко обходятся без заметной производительности, затрат памяти или гибкости кода. MVC просто не подходит для многих вещей в играх. Singleton - это обходной путь для слабых правил статической инициализации C ++, и вам, вероятно, не следует делать это в любом случае. Фабрика упрощает создание сложных объектов - возможно, ваши объекты должны быть проще для начала. Популярные шаблоны - это инструменты, к которым нужно прибегать, когда они нам нужны. чтобы управлять чем-то сложным, а не инструментами, которые мы должны стремиться использовать для создания чего-то сложного в начале.

Хороший (игровой) код может использовать шаблоны или нет. Если он использует шаблоны, хорошо - они являются отличным средством коммуникации, чтобы объяснить структуру кода другим программистам на высоком, независимом от языка уровне. Если вы думаете, что код лучше без использования паттерна, не мучайтесь из-за него - возможно, так оно и есть.

user744
источник
4
Да, одна из вещей, проясненная в оригинальной книге (но часто упускаемая из виду), заключается в том, что если бы она была написана для C, а не для C ++ / Smalltalk, они могли бы включать шаблон «Наследование» и, к тому же, некоторые языки может содержать некоторые из встроенных паттернов GoF.
Kylotan
13
Другая вещь, которую часто упускают из виду в оригинальной книге (оригинальной оригинальной книге Александра, а не GoF), заключалась в том, что шаблоны - это инструмент для общения , а не для реализации . Они позволяют дизайнерам общаться о реализации на более высоком уровне и идентифицируются, потому что они повторяются, а не обязательно, потому что их следует использовать, когда это возможно.
1
Однако простое использование терминологии может помочь вам понять проблему и понять, когда такой подход является хорошим решением. Лучшие образцы, как правило, уточнялись со временем квалифицированными и опытными работниками, и менее квалифицированные работники не могли бы открыть те же самые образцы сами, если бы не было этих кодифицированных примеров.
Kylotan
Я согласен с тем, что наличие терминологии - это прекрасно, и часть определения шаблона заключается в том, что он является хорошим повторяющимся решением для некоторой проблемы. К сожалению, менее квалифицированные работники, как правило, находят в основном синглтон и применяют его к любой проблеме, даже когда проблемы еще нет.
Спасибо за этот ответ; Я с облегчением прочитал, что шаблоны проектирования созданы для решения проблем, создаваемых разработкой программного обеспечения. Я думаю, что структуру целого большого программного обеспечения следует продумывать от начала до конца, прежде чем начинать что-либо кодировать. Вы не можете всегда реализовывать функциональные возможности по одному, иногда вам нужно подумать о каждой конкретной функции и проверить, не будет ли она портиться с глобальной структурой программного обеспечения или просто помешать тому, как программное обеспечение предназначено для этого. вести себя. Разделение задач между несколькими программистами может иногда создавать противоречия ...
Jokoon
7

Конечно, как уже говорили другие, все шаблоны полезны при правильных обстоятельствах, и часть обучения тому, как их использовать, - это изучение того, когда их использовать. Тем не менее, в превосходной книге Даниэля Санчеса-Креспо Далмау « Базовые методы и алгоритмы в игровом программировании » перечислены шесть шаблонов программирования и шесть шаблонов удобства использования, которые особенно полезны в программировании игр.

Программирование:

  • Синглтон: Я не ненавижу этого, как многие люди; его можно использовать для таких вещей, как однопользовательский плеер или клавиатурный ридер.
  • Фабрика: позволяет эффективно создавать и уничтожать объекты.
  • Стратегия: позволяет элегантно менять стратегии ИИ.
  • Пространственный индекс: Помогает выполнять запросы к наборам пространственных данных.
  • Composite: устанавливает полезную иерархию объектов.
  • Flyweight: освобождает память, генерируя такие вещи, как идентичные враги.

Удобство использования:

  • Щит: защищает от случайного включения драматических действий.
  • Состояние: визуальные подсказки о мире / статус пользовательского интерфейса.
  • Отмена автоматического режима: делает игру более интуитивно понятной.
  • Магнетизм: автоматический прицел и легкий выбор единиц.
  • Фокус: устранение отвлекающих элементов пользовательского интерфейса.
  • Прогресс: универсально полезен.

Книга, конечно, более подробно описывает каждый из них.

Gregory Avery-Weir
источник
Спасибо за вклад! Я не знал об этой книге, но сейчас изучу ее в результате вашего поста. Еще раз спасибо!
jcurrie33
2
Синглтон для считывателя клавиатуры - это как раз та ситуация, в которой я должен спросить: неужели вы не можете просто сделать его глобальным указателем, установленным в начале вашей основной функции? Вы когда-нибудь случайно создавали два считывателя клавиатуры?
Пожалуйста, ненавидь синглтон. Это плохо делает две вещи. Глобальный доступ и арность. Часто разработчики думают, что глобальный доступ == синглтон. Там очень мало проблем, чем нужен настоящий синглтон, и, возможно, еще несколько, которые более элегантны при решении с помощью синглтона.
deft_code 17.10.10
7

Системы сущностей - хороший вид паттерна. Это не совсем шаблон дизайна, так как это не странно ООП. Однако вы можете смешать его с ООП.

Несколько хороших ссылок (начните с начала для вступления):

оборота Wernight
источник
3
«Это не совсем шаблон дизайна, так как это не так уж сложно». Шаблоны проектирования не имеют ничего общего с ООП; Во всяком случае, ООП - это шаблон проектирования. Шаблоны проектирования появляются не только за пределами ООП, но и за пределами разработки программного обеспечения.
Есть такие, OOP design patternsкоторые обычно показывают отношения и взаимодействия между классами / объектами. И есть много других шаблонов дизайна. ООП - это набор концепций, а не шаблон. Design patternэто тоже концепция
topright
6
Вместо того, чтобы говорить о семантике, вы не должны оценить полезность ответа, который я дал?
Wernight
6

Все они. Кроме Синглтона. [/ Легкомыслие]

Kylotan
источник
Не могли бы вы назвать один или два шаблона проектирования, которые вы часто использовали при разработке игр, и по какой причине? Как новичок в отношении шаблонов проектирования, «все они» не особенно полезны. Спасибо за ответ, хотя.
jcurrie33
5
Спрашивая "какие шаблоны вы использовали?" это как спросить "какие имена переменных вы использовали?" Это сводится к личному стилю и требованиям и области. В какой-то момент вы, вероятно, будете использовать любой шаблон, который когда-либо был назван. Вы, вероятно, будете использовать гораздо больше, которые не были названы, и, возможно, даже изобрели несколько новых.
@ jcurrie33: извините, я просто не мог устоять перед копанием синглетонов. ;)
Килотан
6

Не совсем о шаблонах, но об основных принципах, лежащих в их основе. В «Шаблонах проектирования: элементы многоразового объектно-ориентированного программного обеспечения» (1995) банда из четырех человек (Гамма, Эрих; Ричард Хелм, Ральф Джонсон и Джон Влиссидес) рекомендует только два принципа для объектно-ориентированного проектирования: (1) программа для интерфейс, а не реализации, и (2) предпочитают композицию объектов наследованию классов.

Эти 2 принципа очень полезны во многих задачах разработки игр. Например, многие программисты игр использовали глубокую иерархию классов для представления игровых сущностей. Существует еще один подход, основанный на композиции - компонентные игровые объекты. Статья об этом подходе. Еще больше ссылок . Это пример шаблона Decorator .

оборота прямо
источник
Компоненты, используемые в игровом дизайне, больше похожи на шаблон стратегии с сохранением состояния - который естественным образом выражается как замыкания вне C / C ++ / Java / C # и как объекты компонентов внутри них. Шаблон декоратора больше похож на прокси; его владение и поток данных противоположны тем, которые мы обычно имеем в виду, когда говорим о компонентных системах в играх.
Компоненты также должны общаться друг с другом, вводя такие шаблоны, как Mediator, Observer и Composer. «Компонентная игра» сама по себе представляет собой сложный шаблон проектирования.
CodexArcanum
@CodexArcanum, Observer, определенно, но не всегда Mediator (вместо этого можно использовать Chain of Responsibility). Это Composer, только если GameObject (составленный из GameObjectComponent) является самим GameObjectComponent (не обязательно).
topright
6

Любопытно повторяющаяся картина шаблона может быть очень полезной для предотвращения виртуальных методов и потери производительности , которые могут исходить от вызовов виртуальных функций.

Это может быть подходящим шаблоном, когда вам на самом деле не нужно иметь контейнер типа базового класса, который имеет интерфейс, который вам нужен, но вы хотели бы иметь поведения и интерфейсы с аналогичными именами.

Например, вы можете использовать это при компиляции классов для нескольких платформ или механизмов (dx против opengl), где дисперсия типа известна во время компиляции.

стог
источник
Я всегда ненавидел, что слой абстракции os был виртуальным. Это не значит, что вам когда-нибудь понадобятся два слоя абстракции. Намного лучше использовать CRTP.
deft_code 17.10.10
Может быть, я просто стар, но я бы даже не использовал CRTP для DX / OpenGL или интерфейсов платформы. Это слишком медленно для компиляции - я бы просто использовал typedefs. CRTP хорош, когда вы хотите обмениваться интерфейсами и реализациями между классами, но не имеете никакого другого отношения, не когда вы просто хотите выбрать одну или другую структуру.
4

Шаблон дизайна, который я развивал в течение многих лет и который был чрезвычайно полезен для меня, - это то, что я называю «набором определений при посредничестве»; то, как его обобщить в терминах GOF, кажется спорным, но этот вопрос, который я написал об этом в StackOverflow, подробно расскажет об этом.

Основная идея заключается в том, что некоторое свойство модели, например вид существа, устанавливается таким образом, чтобы каждое возможное значение свойства имело соответствующий объект определения - один общий объект на значение - который определяет его поведение, и доступ к ним осуществляется через центрального брокера (который, GOF, может быть реестром, фабрикой или обоими). В моем использовании они также обычно доступны через скалярные ключи, чтобы облегчить слабое связывание для целей морфизма во время выполнения.

хаоса
источник
Я вообще не понимаю, как это синглтон, и при обсуждении модели навесного веса слово «реестр» является излишним. Это просто легкий вес.
Мое понимание из потока SO было то, что люди идентифицировали Singleton как часть его из-за определений, заданных как классы. Что касается реестра, я не понимаю, как он может быть избыточным, когда его можно заменить или объединить с Factory.
хаос
-1, в той степени, в которой шаблоны позволяют быстро общаться, это, вероятно, самая большая ошибка, которую я видел. Я действительно не могу принять это описание всерьез.
Господи, прости меня за то, что я не достаточно для тебя печенья. Собираетесь ли вы также голосовать за ответ "Системы сущностей", потому что он не может быть мгновенно суммирован в терминах GOF?
хаос
1
Некоторое количество «печенья», или, по крайней мере, семантической ясности, - это именно то, чем должны быть полезны шаблоны. Такие термины, как «вес в полете» и «синглтон», как они обычно понимаются, являются взаимоисключающими. Первый - это автоматический обмен данными между несколькими экземплярами; Второй - иметь ровно один экземпляр. Я не говорю, что ваш выбор дизайна бесполезен или даже плох, но смешивание «достаточно близких» имен паттернов просто смущает всех больше. (Пожалуйста, не принимайте негативных голосов лично, особенно на CW.)