Как разработать эффективную схему взаимодействия игровых объектов с компонентной архитектурой?


14

Это вопрос дизайна ... Я уверен, что это можно обобщить больше, но мне тяжело с этим. Меня интересует дизайн взаимодействия игровых объектов - вот мой пример (2D-пазл-платформер).

Скажем, игрок пытается пройти уровень. Есть много источников света, которые могут быть направлены в разные стороны. Вот пример того, как эти световые объекты могут взаимодействовать ...

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

Каков наилучший способ решения этой проблемы при использовании компонентной архитектуры? Компоненты для каждого основного объекта кажутся очевидными, так же как и чистый способ определения их воздействия на окружающую среду. Класс для «разрешения» взаимодействия (кажется, что это может быстро стать беспорядком)? Некоторое использование шаблона декоратора для создания объединенных объектов для тех, кто взаимодействует в данный момент времени? Структура данных, которая поддается этому?

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

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

Другая информация: Я использую движок XNA под названием IceCream .



2
Здесь есть актуальный вопрос, в отличие от «вопроса» по ссылке, которую дает Джо.
dash-tom-bang

2
не видите дурака, вопрос в том, как разработать требования к конкретной игре в коде, используя систему компонентов (@Christopher: упомянув, какая из них поможет, вы используете Unity? Torque? Proprietary?)
LearnCocos2D

2
Кстати, мне нравится ваша игровая идея =)
Nailer

Ответы:


5

В объектно-ориентированной системе единственным реальным ответом на вопрос о том, как лучше всего сделать X, является то, что вы должны просто сделать это наиболее простым способом, который вы можете себе представить, чтобы запустить что-то и запустить, а затем изменить его, когда легче выражение становится очевидным. Забота о том, чтобы выбрать правильный шаблон до того, как вы написали какой-либо код, - это хороший способ оседлать себя неправильным ответом с самого начала; пусть все мысли о шаблонах и компонентах растают и просто следуйте этим шагам, начиная с того места, где вы находитесь сегодня (при условии, что вы реализовали легкий компонент):

  1. Добавьте код к легкому компоненту к проектным платформам. (Получите это работает.)
  2. Скопируйте этот компонент в новый компонент, удалите содержимое платформы и добавьте код, чтобы уменьшить трение соответствующих объектов. (Получите это работает, убедитесь, что # 1 все еще работает.)
  3. Скопируйте этот компонент в новый компонент, удалив «новый» код и добавьте материал, чтобы отключить эффекты других компонентов. (Получите это работает, затем убедитесь, что № 1 и № 2 все еще работают.)

На этом этапе у вас (вероятно) будет тонна дублированного кода. Извлечение общего кода в функции или другой класс (может быть, базовый класс) или что-то, что кажется подходящим. То, что вы начали с «легкого компонента», не означает, что LightComponent является подходящей основой; может случиться так, что любой код, составляющий легкий компонент, на самом деле не является «компонентом» как таковым, и, возможно, это будет лучше всего представлено набором функций или даже отдельным классом, который агрегируется в ваши новые компоненты (как переменная-член ).


Я отмечаю это как ответ, потому что он действительно отвечает «Как я должен проектировать ...». Спасибо за это, это определенно поставило меня на правильный путь.
Кристофер Хоренштейн

2

В общих чертах, когда объект типа A взаимодействует с объектом типа B, вы хотите получить некоторый эффект C. Это называется «двойной диспетчеризацией», и это очень сложно сделать элегантно в C-подобных языках.

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

Шаблон для посетителей является более надежным решением , которое скрывает неприятное переключение типа, но может быть clumbersome установить.

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


2

Дайте-ка подумать. Это просто то, что я приготовил в голове, когда писал, так что извините, если что-то упустил.

Получите все легкие узлы на разумном расстоянии вокруг вашего парня.

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

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

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

Грубый эскиз, сделанный за 2 минуты, как бы иллюстрирует мою идею:

иллюстрация

Изменить: На практике это означает, что единственное, что вам нужно, это один компонент света, излучающий определенный цвет. Правила, связанные с тем, что цвет делает то, что может быть где-то еще полностью. Вы можете закодировать много данных в 32-битный пиксель. В качестве альтернативы вы можете иметь несколько FBO, содержащих различные атрибуты, которые не влияют друг на друга. Вы могли бы иметь одно FBO гравитации / трения и одно 1-битное FBO столкновения. Если вы выберете это, вам, конечно, нужно будет указать, в какое FBO должен направляться ваш свет.


Спасибо за ваш вклад. Я действительно ценю визуальные эффекты, и это действительно заставило меня задуматься о том, как механик может работать за сценой.
Кристофер Хоренштейн

Хех, нет проблем. Я знаю, что это не ответило на ваш точный вопрос, но некоторые проблемы требуют специализированных решений. Удачи!
Nailer

0

Шаблон Observer является одним из лучших решений. Сообщение будет отправлено только тем объектам (компонентам), которые действительно в нем заинтересованы. Поэтому получатель должен подписаться на это сообщение / тип события.

Существует много реализаций сигналов / слотов. Например, в C ++ есть библиотека sigslot

Для получения дополнительной информации читайте о сигналах и слотах Qt .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.