Традиционный дизайн игры , как я это знаю, использует полиморфизм и виртуальные функции для обновления игры объектов состояния. Другими словами, один и тот же набор виртуальных функций вызывается через регулярные (например, за кадр) интервалы для каждого объекта в игре.
Недавно я обнаружил, что существует другая система сообщений, управляемая событиями, для обновления состояний игровых объектов. Здесь объекты обычно не обновляются для каждого кадра. Вместо этого создается высокоэффективная система обмена сообщениями о событиях , и игровые объекты обновляются только после получения действительного сообщения о событии.
Игровая архитектура, управляемая событиями, подробно описана в статье : « Кодирование игр завершено Майком МакШаффри» .
Могу ли я попросить помощи по следующим вопросам:
- Каковы преимущества и недостатки обоих подходов?
- Где одно лучше другого?
- Является ли управляемый событиями игровой дизайн универсальным и лучшим во всех областях? Поэтому рекомендуется для использования даже на мобильных платформах?
- Какой из них более эффективен, а какой сложнее развивать?
Чтобы уточнить, мой вопрос не о том, чтобы полностью удалить полиморфизм из игрового дизайна. Я просто хочу понять разницу и извлечь выгоду от использования событийно-ориентированного обмена сообщениями по сравнению с обычными (для каждого кадра) вызовами виртуальных функций для обновления состояния игры.
Пример: этот вопрос вызвал здесь некоторые противоречия, поэтому позвольте мне привести вам пример: согласно MVC, движок игры разделен на три основные части:
- Уровень приложений (аппаратное обеспечение и связь с ОС)
- Игровая логика
- Просмотр игры
В гоночной игре Game View отвечает за максимально быстрое отображение экрана, по крайней мере, 30 кадров в секунду. Game View также прослушивает вход игрока. Теперь это происходит:
- Игрок нажимает педаль топлива до 80%
- GameView создает сообщение «Педаль топлива 2 нажата до 80%» и отправляет его в Game Logic.
- Game Logic получает сообщение, оценивает, рассчитывает положение и поведение нового автомобиля и создает для GameView следующие сообщения: «Нажата педаль топлива Draw 2, нажато на 80%», «Ускорение звука автомобиля 2», «Координаты автомобиля 2 X, Y» .. ,
- GameView получает сообщения и обрабатывает их соответственно
источник
update
их). Второе вы можете сделать с сообщениями по разным причинам.Ответы:
Я полностью верю в необходимость быть матерью изобретения. Я не люблю ничего кодировать, если это не нужно четко и четко определено. Я думаю, что если вы начинаете свой проект с установки системы обмена сообщениями о событиях, вы делаете это неправильно. Я считаю, что только после того, как вы создадите и протестируете свою инфраструктуру и будете иметь все элементы для своего проекта в виде четко определенных рабочих модулей, вы должны сосредоточиться на том, как вы собираетесь соединять эти модули друг с другом. Попытка разработать систему обмена сообщениями о событиях, прежде чем вы поймете форму и потребности каждого модуля, вышла из строя.
Каковы преимущества и недостатки обоих подходов?
Я думаю, что некоторые люди будут утверждать, что есть хорошие системы обмена сообщениями, готовые к установке и использованию. Возможно, это правда. Конечно, производительность решения для индивидуальной сборки, специально разработанного для ваших нужд, будет выше, чем для шины сообщений общего назначения. Большой вопрос - сколько времени вы собираетесь потратить на создание системы обмена сообщениями, а не на использование того, что уже было создано. Очевидно, что если бы вы могли найти какую-то систему событий с именно тем набором функций, который вам нужен, то это довольно простое решение. Вот почему я делаю все, чтобы понять, что мне нужно, прежде чем принять это решение.
Где одно лучше другого?
Мы могли бы поговорить о памяти и ресурсах здесь. Если вы разрабатываете для какого-либо оборудования с ограниченными ресурсами, это, безусловно, проблема в использовании системы событий, которая значительно снизит это. Правда, я думаю, что проблема сводится к тому, что вам нужно, что, как я уже говорил, вы не знаете, пока не увидите, как выглядят все части. Если у вас достаточно опыта по созданию этих систем, и вы заранее точно знаете, как будут выглядеть все компоненты, вы также можете заранее ответить на этот вопрос. Я предполагаю, что у вас нет этого опыта, так как вы бы не задавали этот вопрос, если бы у вас был.
Является ли управляемый событиями игровой дизайн универсальным и лучшим во всех областях? Поэтому рекомендуется для использования даже на мобильных платформах?
Универсальный и лучший во всех областях? Такое довольно общее утверждение легко отвергается. Все, что добавляет накладные расходы, должно нести свою долю рабочей нагрузки. Если вы не используете события в достаточной мере, чтобы оправдать накладные расходы на дизайн, значит, это неправильный дизайн.
Какой из них более эффективен, а какой сложнее развивать?
Эффективность зависит от того, как это реализовано. Я думаю, что хорошо разработанный традиционный дизайн превзойдет систему, основанную на событиях, в любой день недели. Это потому, что связь между частями может быть микроуправляемой и очень эффективной. Конечно, это также усложняет разработку с точки зрения опыта и времени, необходимого для его завершения и повышения его эффективности. С другой стороны, если вам не хватает этого опыта или у вас нет времени, чтобы хорошо разработать приложение, тогда использование основанного на событиях дизайна, которое соответствует вашим потребностям, будет более эффективным. Если у вас есть особые потребности в мероприятиях, которые не легко вписываются в структуру, основанную на событиях, это может сделать структуру, основанную на событиях, очень трудной для разработки, особенно для сохранения эффективности проекта.
источник
Я думаю, что вы сравниваете яблоки и апельсины здесь. Полиморфизм вообще не заменяется обменом сообщениями. Возможно, вы захотите, чтобы события / сообщения связывали слабосвязанные компоненты. Например. отправить сообщение от объекта при столкновении, обновить счет игрока или, может быть, вызвать звуковой эффект. Так что эти отдельные классы не знают других классов и просто отправляют и / или обрабатывают сообщения.
Но ваша игра, скорее всего, будет где-то иметь цикл обновления, и так как у вас есть цикл обновления, этот цикл обновления, его можно легко использовать для обновления всех игровых объектов, которые также должны обновляться в каждом кадре. Это не мешает вам использовать обмен сообщениями, хотя ...
Если у вас есть какая-то структура, в которой вы добавляете / удаляете игровые сущности, вы также можете включить их в свой цикл обновления вместо того, чтобы отправлять им сообщение об обновлении каждый кадр. Так почему бы не вызвать обновление ваших игровых сущностей напрямую, когда вы используете обмен сообщениями для подключения различных подсистем вашей игры? Мне также нравится концепция Signal / Slot ( см. Пример qt ) для систем, подобных событиям.
Итог: нет лучшего подхода, и при этом они не исключительны.
источник
Это началось как комментарий к ответу bummzack, но получилось долго.
Если вы на самом деле не сделаете это асинхронным (отправка событий в новом потоке), ваши объекты все равно будут получать памятку синхронно. Предполагая, что ваш диспетчер событий использует базовую хеш-таблицу со связанным списком в ячейке, порядок будет таким, в котором объекты были добавлены в эту ячейку.
Кроме того, если вы по какой-то причине не решите использовать указатели функций, вы все равно будете использовать вызовы виртуальных функций, поскольку каждый объект, получающий сообщение, должен реализовывать IEventListener (или как вы его называете). События - это абстракция высокого уровня, которую вы строите с использованием полиморфизма.
Используйте события, когда вам приходится вызывать подробный список методов для различных внутриигровых событий, чтобы синхронизировать различные системы в игре или когда реакция различных объектов и систем на такие события не может быть четко определена или вы хотите добавить больше реакций на эти события в будущем.
Это отличный инструмент, но, как сказал Буммзак, не думайте, что полиморфизм и события решают одну и ту же проблему.
источник
Я бы сказал, что выбор одного или другого довольно неправильный. Некоторые объекты должны вызывать каждый кадр, а некоторые нет. Если у вас есть объект, который вы хотите визуализировать, вам нужно вызывать его каждый кадр. События не могут сделать это изменение. То же самое верно для любых основанных на времени физических объектов - вы должны называть их каждый кадр.
Тем не менее, я не обращаюсь каждый кадр к моим объектам управления объектами, или к объектам пользовательского ввода, или к чему-либо подобному. Массовые виртуальные звонки на каждый объект в кадре - ужасная идея.
Проект, используемый для любого конкретного объекта, должен основываться на потребностях этих объектов, а не на некоторой идеологии для системы в целом.
Отредактировано, чтобы быть более ясным в моем первом предложении.
источник