Это вопрос дизайна ... Я уверен, что это можно обобщить больше, но мне тяжело с этим. Меня интересует дизайн взаимодействия игровых объектов - вот мой пример (2D-пазл-платформер).
Скажем, игрок пытается пройти уровень. Есть много источников света, которые могут быть направлены в разные стороны. Вот пример того, как эти световые объекты могут взаимодействовать ...
- Один свет проецирует платформу, которая позволяет игроку преодолеть разрыв
- Один свет уменьшает коэффициенты трения всего, к чему он прикасается, другой увеличивает его
- Один источник света обнуляет эффекты всех источников света, что приводит к исчезновению платформы при включенном свете и обнулению модификаторов трения.
- И т.д...
Каков наилучший способ решения этой проблемы при использовании компонентной архитектуры? Компоненты для каждого основного объекта кажутся очевидными, так же как и чистый способ определения их воздействия на окружающую среду. Класс для «разрешения» взаимодействия (кажется, что это может быстро стать беспорядком)? Некоторое использование шаблона декоратора для создания объединенных объектов для тех, кто взаимодействует в данный момент времени? Структура данных, которая поддается этому?
Кроме того, подключение аудио к этим взаимодействиям? Кажется, что подключение аудио к системе было бы похоже на подключение любого другого свойства, например, видимости или движения / столкновения игрока.
Очевидно, что по мере добавления большего количества компонентов было бы неплохо, если бы существовала надежная система, которая могла бы обрабатывать новые с небольшими изменениями, но я не знаю, как это сделать.
Другая информация: Я использую движок XNA под названием IceCream .
источник
Ответы:
В объектно-ориентированной системе единственным реальным ответом на вопрос о том, как лучше всего сделать X, является то, что вы должны просто сделать это наиболее простым способом, который вы можете себе представить, чтобы запустить что-то и запустить, а затем изменить его, когда легче выражение становится очевидным. Забота о том, чтобы выбрать правильный шаблон до того, как вы написали какой-либо код, - это хороший способ оседлать себя неправильным ответом с самого начала; пусть все мысли о шаблонах и компонентах растают и просто следуйте этим шагам, начиная с того места, где вы находитесь сегодня (при условии, что вы реализовали легкий компонент):
На этом этапе у вас (вероятно) будет тонна дублированного кода. Извлечение общего кода в функции или другой класс (может быть, базовый класс) или что-то, что кажется подходящим. То, что вы начали с «легкого компонента», не означает, что LightComponent является подходящей основой; может случиться так, что любой код, составляющий легкий компонент, на самом деле не является «компонентом» как таковым, и, возможно, это будет лучше всего представлено набором функций или даже отдельным классом, который агрегируется в ваши новые компоненты (как переменная-член ).
источник
В общих чертах, когда объект типа A взаимодействует с объектом типа B, вы хотите получить некоторый эффект C. Это называется «двойной диспетчеризацией», и это очень сложно сделать элегантно в C-подобных языках.
Эффективный, но сложный в обслуживании способ - это просто набор переключателей и операторов if в зависимости от типов ваших объектов. Вы почувствуете себя грязно, написав это, но это сделает работу.
Шаблон для посетителей является более надежным решением , которое скрывает неприятное переключение типа, но может быть clumbersome установить.
Обычно любой тип переключения типов в вашем коде - это запах, но здесь вы пытаетесь обобщить полиморфизм, который обычно переключает функции на основе одного типа, чтобы переключать функции на основе двух типов. Полиморфизм - это основа ООП, поэтому он не пахнет.
источник
Дайте-ка подумать. Это просто то, что я приготовил в голове, когда писал, так что извините, если что-то упустил.
Получите все легкие узлы на разумном расстоянии вокруг вашего парня.
Для каждого источника света вы визуализируете полигон, представляющий его область действия, объекту кадрового буфера. Таким образом, конус света создаст конус одного типа пикселей в вашем FBO. Визуализируйте каждый тип узла в проходах с соответствующим приоритетом. Вы можете закодировать информацию в каждый пиксель, как зеленый канал может быть трением, красный - гравитацией, синий и альфа - чем-то другим.
Умные методы смешения цветов могут создать интересные эффекты. Каждый уровень может иметь свои собственные правила смешивания. Вы также можете добавить затенение фрагмента для психоделических динамических эффектов, таких как пульсирующая гравитация и т. Д.
Наконец, просто проверьте, к каким пикселям относится ваш мандуд, и выполняйте пересчет растрового изображения, когда вы приближаетесь к краям предварительно вычисленной области.
Грубый эскиз, сделанный за 2 минуты, как бы иллюстрирует мою идею:
Изменить: На практике это означает, что единственное, что вам нужно, это один компонент света, излучающий определенный цвет. Правила, связанные с тем, что цвет делает то, что может быть где-то еще полностью. Вы можете закодировать много данных в 32-битный пиксель. В качестве альтернативы вы можете иметь несколько FBO, содержащих различные атрибуты, которые не влияют друг на друга. Вы могли бы иметь одно FBO гравитации / трения и одно 1-битное FBO столкновения. Если вы выберете это, вам, конечно, нужно будет указать, в какое FBO должен направляться ваш свет.
источник
Шаблон Observer является одним из лучших решений. Сообщение будет отправлено только тем объектам (компонентам), которые действительно в нем заинтересованы. Поэтому получатель должен подписаться на это сообщение / тип события.
Существует много реализаций сигналов / слотов. Например, в C ++ есть библиотека sigslot
Для получения дополнительной информации читайте о сигналах и слотах Qt .
источник