Виклики функцій за кадром та повідомленнями, керовані подіями в дизайні ігор


11

Традиційний дизайн гри , як я це знаю, використовує поліморфізм і віртуальні функції для поновлення гри об'єктів стану. Іншими словами, один і той же набір віртуальних функцій викликається в регулярних (наприклад: за кадром) інтервалах для кожного об'єкта в грі.

Нещодавно я виявив, що існує інша система обміну повідомленнями, керована подіями, для оновлення станів ігрових об'єктів. Тут об'єкти зазвичай не оновлюються на основі кадру. Натомість будується високоефективна система обміну повідомленнями про події , а ігрові об’єкти оновлюються лише після отримання дійсного повідомлення про подію.

Керована подіями архітектура ігор добре описана в: Кодування гри завершено Майком МакШафрі .

Чи можу я просити про допомогу з наступними питаннями:

  • Які переваги та недоліки обох підходів?
  • Де один кращий за іншого?
  • Чи є дизайн ігор універсальним і кращим у всіх сферах? Тому це рекомендується використовувати навіть на платформах для мобільних телефонів?
  • Який з них більш ефективний, а який складніший для розвитку?

Для уточнення, моє питання не в тому, щоб повністю зняти поліморфізм з ігрового дизайну. Я просто хочу зрозуміти різницю та вигоду від використання обміну повідомленнями подій проти звичайних (за кадром) дзвінків до віртуальних функцій для оновлення ігрового стану.


Приклад: Це запитання викликало тут трохи суперечок, тому дозвольте запропонувати вам приклад: За даними MVC, ігровий движок розділений на три основні частини:

  1. Прикладний рівень (апаратне забезпечення та ОС)
  2. Логіка гри
  3. Перегляд гри

У гоночній грі Game View відповідає за максимально швидке відображення екрана, принаймні 30 кадрів в секунду. Game View також слухає дані гравця. Зараз це відбувається:

  • Гравець натискає педаль палива до 80%
  • GameView створює повідомлення "Нагнітається паливна педаль автомобіля до 80%" і надсилає її до Game Logic.
  • Game Logic отримує повідомлення, оцінює, обчислює положення та поведінку нового автомобіля та створює такі повідомлення для GameView: "Намалюйте педаль палива для автомобіля 2 на 80%", "Прискорення звуку автомобіля 2", "Координати автомобіля 2 X, Y". .
  • GameView отримує повідомлення та обробляє їх відповідно

де ти знайшов? деякі посилання чи посилання? Я не знаю такого підходу (але я знаю досить загальну модель дизайну, але я раджу щодо використання принципів об'єктних орієнтацій взагалі), але я думаю, що на основі подій краще. Подумайте про еволюцію в мережевих системах: від опитування на асинхронні дзвінки .. вона оптимізована в обчисленнях і на рівні абстракції
nkint

Привіт Nkint, дякую за Ваш коментар. Я в основному хотів порівняти комунікацію, керовану подіями, і виклики з віртуальними функціями. Я трохи зміню своє запитання. Btw, подивіться на це посилання, що містить шаблони ігор для ігор: gameprogrammingpatterns.com .
Bunkai.Satori

5
Можливо, я німий, але як ти збираєшся змусити роботу системи обміну повідомленнями, не використовуючи поліморфізм? Вам не знадобиться якийсь базовий клас (абстрактний чи інший) для визначення інтерфейсу приймача подій? (Редагувати: якщо припустити, що ви не працюєте мовою з належним відображенням.)
Тетрад

2
Крім того, ефективність буде сильно пов'язана з деталями впровадження. Я не думаю, що "хто з них більш ефективний" - це питання, на яке можна відповісти в його теперішній формі.
Тетрад

1
Ігрові об’єкти потрібно поставити галочку. Ігрові об’єкти потребують спілкування один з одним. Ці дві речі повинні відбутися. Перше, що ви не робите з обміну повідомленнями, оскільки це зайве (у вас, мабуть, є список усіх об'єктів десь, просто зателефонуйте updateдо них). Друге, що ви можете зробити з повідомленнями з різних причин.
Тетрад

Відповіді:


8

Я повністю вірю в необхідність бути матір'ю винахідництва. Я не люблю нічого кодувати, якщо її потреба не є чіткою та чітко визначеною. Я думаю, що якщо ви починаєте свій проект, налаштовуючи систему обміну подіями, ви робите це неправильно. Я вважаю, що лише після того, як ви створили та протестували свою інфраструктуру та отримали всі деталі для вашого проекту як чітко визначені, працюючі модулі, ви повинні зосередитись на тому, як ви збираєтесь з'єднати ці модулі один з одним. Намагаючись створити систему обміну подіями, перш ніж зрозуміти форму та потреби кожного модуля, вийшов із ладу.

Які переваги та недоліки обох підходів?

Я думаю, що деякі люди будуть стверджувати, що там є хороші системи обміну повідомленнями, готові до встановлення та використання. Можливо, це правда. Безумовно, ефективність розробленого на замовлення рішення, спеціально з урахуванням ваших потреб, буде більшою, ніж шина повідомлень загального призначення. Велике питання - скільки часу ви збираєтеся витратити на створення системи обміну повідомленнями, а не на використання вже створеного. Очевидно, що якщо ви змогли знайти якусь систему подій з саме потрібним набором функцій, то це досить просте рішення. Ось чому я переконуюсь, що я розумію саме те, що мені потрібно, перш ніж приймати це рішення.

Де один кращий за іншого?

Тут ми могли б поговорити про пам'ять та ресурси. Якщо ви розробляєте для будь-якого обладнання з обмеженими ресурсами, звичайно, проблема використовувати систему подій, яка суттєво вирішить це. Дійсно, однак, я думаю, що питання зводиться до того, що вам потрібно, що, як я вже згадував, - це те, про що ви не знаєте, поки не побачите, як виглядають усі шматки. Якщо у вас є достатній досвід створення цих систем, який ви заздалегідь знаєте, як саме виглядатимуть усі деталі, то ви можете відповісти на це питання також заздалегідь. Я здогадуюсь, що у вас немає цього досвіду, оскільки ви б не ставили цього питання.

Чи є дизайн ігор універсальним і кращим у всіх сферах? Тому це рекомендується використовувати навіть на мобільних платформах?

Універсальний і кращий у всіх сферах? Симпатичне бланк подібне твердження легко відкидається. Все, що додає накладні витрати, має нести свою частку навантаження. Якщо ви не використовуєте події достатньо, щоб гарантувати накладні витрати дизайну, то це неправильний дизайн.

Який з них більш ефективний, а який складніший для розвитку?

Ефективність залежить від того, наскільки його реалізовано. Я думаю, що добре розроблений традиційний дизайн випереджає систему, засновану на заходах, у будь-який день тижня. Це тому, що спілкування між шматками може бути мікро-керованим і зробити надзвичайно ефективним. Звичайно, це також ускладнює проектування з точки зору досвіду та часу, необхідного для його завершення та підвищення ефективності. З іншого боку, якщо вам не вистачає цього досвіду або у вас немає часу для того, щоб добре розробити додаток, то використання на основі подій дизайну, який відповідає вашим потребам, буде більш ефективним. Якщо у вас є потреби в подіях, які не вписуються в структуру, що базується на подіях, це може ускладнити проектування структури подій, особливо для забезпечення ефективності дизайну.


Привіт Еріку, дякую за детальну думку щодо мого запитання. Коли я читаю ваші та інші відповіді, реалізація повідомлень про події, ймовірно, не спричиняє дива у загальному збільшенні продуктивності гри. Натомість це значно ускладнить справи. Я хотів би побачити ще кілька відповідей, перш ніж закрити це питання. Оскільки ця книга висвітлювала цю тему, це виглядало як гарна ідея. Я не дуже впевнений, що рішення про використання або не використання повідомлень може бути прийнято в середині проекту. Якщо використовуються повідомлення про події, я б сказав, загальний дизайн об'єкта теж повинен бути скоригований.
Bunkai.Satori

Я не погоджуюсь. Якщо загальний дизайн об'єкта добре інкапсульований, він повинен бути досить гнучким, щоб використовувати його в будь-якому обрамленні. Мені вдалося замінити методи спілкування у великих проектах з дуже малою роботою, тому що кожен твір був добре укладений.
Ерік Робертсон

7

Я думаю, ви порівнюєте тут яблука та апельсини. Поліморфізм взагалі не замінюється повідомленнями. Ймовірно, ви хочете, щоб події / обмін повідомленнями з’єднували слабко з'єднані компоненти. Напр. щоб надіслати повідомлення від сутності при зіткненні, оновити рахунок гравця або, можливо, викликати звуковий ефект. Так що ці окремі класи не знають інших класів і просто надсилають та / або обробляють повідомлення.

Але ваша гра, швидше за все, десь матиме цикл оновлення, і оскільки у вас є цикл оновлення, його можна легко використовувати для оновлення всіх ігрових об'єктів, які потребують оновлення кожного кадру. Це не заважає вам використовувати обмін повідомленнями, хоча ...

Якщо у вас є якась структура, де ви додаєте / видаляєте ігрові сутності, ви можете так само добре включати їх у цикл оновлення, а не надсилати повідомлення про оновлення до кожного кадру. То чому б не зателефонувати на оновлення ваших ігрових організацій безпосередньо, коли ви використовуєте обмін повідомленнями для підключення різних підсистем вашої гри? Мені також подобається концепція сигналів / слотів ( див. Приклад qt ) для подібних до подій систем.

Суть: Ні кращого підходу, ні вони не є ексклюзивним.


Привіт, Баммзак. Нарешті прийшла перша відповідь. Дякую за це :-) Коли я згадав архітектуру, керовану подією, я мав на увазі систему MVC з трьома ключовими шарами: Appliaction, GameView, GameLogic. Весь зв’язок між цими трие буде здійснюватися через обмін повідомленнями. Це суттєво відрізняється від традиційної системи з циклом оновлення. Кожна система має різну архітектуру, деякі переваги та недоліки, і вони мають різну вартість продуктивності. Тому я вважаю, що в деяких сферах було б трохи краще. Після хорошого аналізу ми зможемо зробити висновок, який із них кращий.
Bunkai.Satori

3
Я не розумію, чому це все інакше? Вам десь знадобиться цикл оновлення, і це, ймовірно, оновить Контролер, якщо ви хочете дотримуватися MVC. Тоді контролер може надсилати повідомлення про модель та вигляд .. але оскільки контролер зазвичай знає вигляд та модель, він також може безпосередньо їх оновлювати. Але це не замінює жодного поліморфізму. Ваше запитання та припущення звучать дуже теоретично ... можливо, підкріпіть їх прикладом коду чи деякими посиланнями?
bummzack

Згадана вище книга, Кодування ігор завершено, рекомендує обмін повідомленнями подій через прямі дзвінки до віртуальних методів. Хоча система обміну повідомленнями виглядає більш складною, її перевага полягає в тому, що кожному ігровому об'єкту не потрібно перевіряти ігровий світ. Ігровий світ перевіряється логікою гри лише один раз, і тоді адресовані лише ті об’єкти, які повинні змінити стан. Це одна різниця, і може означати економію витрат. Якщо ви вирішите, що ваші ігрові об’єкти будуть спілкуватися за допомогою повідомлень, вони не будуть називатися кожним кадром - тому два підходи взаємовиключні.
Bunkai.Satori

1
Голосований за відповідь, що відображає коментарі Тетрада нижче початкового питання. @ Bunkai.Satori "Ігровий світ перевіряється лише один раз" - це цикл оновлення, все, що потребує оновлення, отримує. Повідомлення подій мають бути рідко зробленими, але все-таки ключовими речами в двигуні (PlayerDied, MonsterDied тощо), за допомогою яких перевірка кожного кадру в циклі оновлення () буде даремно, але вони, швидше за все, будуть генеровані Оновити цикл ().
Джеймс

1
Якщо у вас є Друге видання, подивіться розділ під назвою Контроль головної петлі. Це ж саме слід назвати у 3-му виданні. Це дійсно повинно відповісти на ваше запитання.
Рей Дей

4

Це почалося як коментар до відповіді bummzack, але отримало довго.

Якщо ви насправді не зробите його асинхронним (відправлення подій у новій потоці), ваші об'єкти все ще отримують нагадування синхронно. Якщо припустити, що ваш диспетчер подій використовує основну хеш-таблицю із пов'язаним списком у комірці, порядком буде порядок, у якому об’єкти були додані до цієї комірки.

Крім того, якщо ви не вирішите використовувати покажчики функцій з якихось причин, ви все ще використовуєте віртуальні виклики функцій, оскільки кожен об'єкт, що отримує повідомлення, повинен реалізовувати IEventListener (або як би ви його називали). Події - це абстракція високого рівня, яку ви будуєте, використовуючи поліморфізм.

Використовуйте події, коли вам доведеться зателефонувати до списку білизни методів для різних ігрових подій, щоб синхронізувати різні системи в грі, або коли різні реакції об'єктів і систем, так що зазначені події не можуть бути чітко визначені або ви хочете щоб додати більше реакцій на ці події в майбутньому.

Вони є чудовим інструментом, але, як сказав Бамзак, не вважайте, що поліморфізм та події вирішують ту саму проблему.


Привіт Bearcdp, дякую за вашу відповідь. Для мене це має сенс. Я маю на увазі одне, що голосує за повідомлення про події: скажімо, на сцені є 200 відхилень. Якщо ви використовуєте виклики функцій за кадром для всіх об'єктів, вам потрібно перевірити всі 200 об'єктів на предмет зібрання кожного кадру (приклад; звичайно, інтервалами дзвінків можна керувати.) Під час обміну повідомленнями подій ігровий світ досліджується лише один раз. Якщо відбувається 5 зіткнень, то лише 5 об’єктів отримують повідомлення про події зіткнення замість 200 тестів на виявлення зіткнення з викликами на кадр Яка ваша думка?
Bunkai.Satori

2
вивчити ігровий світ ?? що це означає? Це повинно означати проведення тих же 200 перевірок, щоб виділити 5, про які потрібно відправляти повідомлення. З концепцією віртуальної функції ігровий світ перевіряється лише один раз (функція кожного об'єкта по черзі), а потім переходить на лише 5, які потребують змін стану ... без накладних витрат системи обміну повідомленнями.
Стів H

1
Послухайте Стіва Н, світ не зіткнеться сам. Я в основному використовую події для подій високого рівня, таких як PlayerJump, EnemyHit. Для управління ефективністю перевірки зіткнень потрібно вибрати структуру даних для організації фізичного розташування об'єктів у вашій грі, щоб ви могли визначити, які об’єкти потребують, а чи не потрібно перевіряти на зіткнення. Визначивши всі пари об'єктів, що зіткнулися, ви можете відправити подію з відповідними даними зіткнення (два об'єкти, дані про швидкість / положення / нормалі тощо).
michael.bartnett

Привіт, Стів та Beardcp, дякую за ваші коментарі. Те, що ви написали, має сенс. Схоже, може бути багато можливих реалізацій системи обміну подіями. Там може бути чиста заміна концепції кадру віртуальної функції, як сказано у вищезгаданій книзі. Однак система обміну повідомленнями, як ви кажете, може співіснувати з концепцією віртуальної функції на кадр.
Bunkai.Satori

Чому ви говорите "чомусь" посилаючись на функціональні вказівники? Це майже те, як я реалізував систему подій, коли я писав її з нуля (я працюю мовами, які мають функції першого класу, але це та сама ідея; передайте функцію об'єкту центру подій, і цей об'єкт відображає функції слухача на події), тому мені цікаво, чи є недолік у цього підходу.
поштовх

2

Я б сказав, що обирати те чи інше - досить неправильно. Деякі об’єкти потребують виклику кожного кадру, а деякі - ні. Якщо у вас є об'єкт, який ви хочете візуалізувати, вам потрібно зробити виклик візуалізації до нього в кожному кадрі. Події не можуть змінити це. Те саме стосується будь-яких фізичних об'єктів, заснованих на часі - ви повинні викликати їх у кожному кадрі.

Однак я не здійснюю дзвінки кожного кадру на свої об'єкти управління об'єктами, або на мої об'єкти введення користувача, або щось подібне. Масові віртуальні дзвінки до кожного об'єкта на кадрі - жахлива ідея.

Дизайн, який використовується для будь-якого конкретного об'єкта, повинен базуватися на потребах цих об'єктів, а не базуватися на певній ідеології для системи в цілому.

Відредаговано, щоб бути більш зрозумілим у моєму першому реченні.


Привіт DeadMG, дозвольте мені пояснити: У вищезгаданому випадку дизайн розділений на три основні частини: рівень додатку (апаратний доступ), логіка гри, перегляд гри. Що виводиться на основі кадру, це перегляд гри. Однак, коли Game View записує вхід користувача (наприклад, натиснута педаль гальма в грі), він надсилає повідомлення «Автомобіль 2 натиснуто на гальмо» в «Логіку гри» для обробки. Ігрова логіка оцінює цю дію, обчислює поведінку автомобіля та надсилає повідомлення в режим перегляду гри: "Автомобіль 2 блок-шини", "Автомобіль 2 Переїзд до X, Y". Таким чином, не потрібно перевіряти за кадром, чи було натиснуто гальмо на кожній машині.
Bunkai.Satori

@Bunkai: Отже, у вас є деякі проекти, керовані подіями, і деякі проекти, які називаються кожним кадром. Це майже погоджується з моєю відповіддю.
DeadMG

Я радий знайти взаєморозуміння з вами, оскільки сьогодні це питання було трохи суперечливим :-)
Bunkai.Satori
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.