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


12

Я працюю над простою головоломкою на основі блоків.

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

Я розділив код на дві області: логіка гри та інтерфейс користувача, як я робив із багатьма головоломками:

  • Логіка гри відповідає за загальні правила гри (наприклад, формальна система правил у шахах)
  • Користувацький інтерфейс відображає ігрову область та фігури (наприклад, шахова дошка та шматки) і відповідає за анімацію (наприклад, анімаційний рух шахових фігур)

Логіка гри представляє ігровий стан як логічну сітку, де кожна одиниця є шириною / висотою однієї комірки в сітці. Отже, для сітки шириною 6 можна перемістити блок шириною 2 чотири рази, поки він не зіткнеться з межею.

Користувацький інтерфейс приймає цю сітку і малює її, перетворюючи логічні розміри в розміри пікселів (тобто помножує її на постійну). Однак, оскільки гра майже не має логіки гри, мій ігровий рівень логіки [1] не має нічого спільного, крім виявлення зіткнень. Ось як це працює:

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

Я не дуже задоволений цим:

  • Я пишу одиничні тести для мого логічного шару гри, але не інтерфейсу користувача, і виявилося, що весь хитромудрий код є в інтерфейсі: Зупинення шматка від зіткнення з іншими або кордону та прив’язування до сітки.
  • Мені не подобається те, що інтерфейс користувача розказує логіку гри про новий стан, я б скоріше за все це назвав movePieceLeft()методом чи чимось подібним, як у інших моїх іграх, але мені не вдалося далеко підійти до цього підходу, оскільки логіка гри нічого не знає про перетягування та оснащення, що можливо в інтерфейсі користувача.

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

  1. Чи є такий фізичний шар загальним чи більш типовим є те, щоб логічний шар гри це робив?
  2. Чи належить прив'язування до сітки та коду перетягування фрагментів користувальницькому інтерфейсу або фізичному шару?
  3. Чи може такий рівень фізики працювати з розмірами пікселів або з якоюсь логічною одиницею, як-от мій логічний шар гри?
  4. Я колись бачив виявлення зіткнень на основі подій у базі коду гри, тобто гравець просто перетягуватиме частину, інтерфейс інтерфейсу візуалізує це та повідомляє фізичну систему, а фізична система викликає метод onCollision () на деталі, коли виявлено зіткнення. Що є більш поширеним? Такий підхід чи спочатку вимагає сфери легального руху?

[1] шар , напевно, не є правильним словом для того, що я маю на увазі, але підсистема звучить перекрито, і клас помилково керується, оскільки кожен шар може складатися з декількох класів.


Чи допомогла моя відповідь, потрібна додаткова інформація?
Буде Маркуйлер

Будь ласка, або підкажіть, і прийміть відповідь, якщо це допомогло, або розкажіть про ваші проблеми із впровадженням такої архітектури чи щось подібне, але повідомляйте нас про вашу ситуацію, щоб ми могли бути кориснішими. =)
Буде Маркуйлер

Відповіді:


3

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

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

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

Отже, ось мої думки з цієї теми - сподіваюся, що це допоможе:

  1. Шар GUI: Цей шар повинен містити методи лише для відображення фрагментів на ігровій дошці, щоб забезпечити взаємодію між самою грою та гравцем;
  2. Шар ігрового контролера: відповідає за входи гравця. Це шар, який повинен підказати фігурі рухатися в різних напрямках, і запитати ігрову дошку, чи будуть зіткнення при русі тощо;
  3. Діловий рівень: Цей шар містить усі ваші бізнес-класи, тобто фрагменти вашої гри та об’єкт ігрової дошки, який містить частини головоломки.

У цій архітектурі ви мали б на шарі GUI показати гравця стану гри, розташування кожного фрагмента головоломки. Потім графічний інтерфейс повинен відповідати за отримання входів програвача та передачу його в базовий рівень ігрового контролера, який потім буде відповідальним за виявлення зіткнень. Якщо його немає, то фрагмент можна доручити рухатись у той напрямок введення. Для цього вам просто доведеться називати цей твір MoveLeft,MoveRightі т. д. методи змусити деталь рухатись. Ви також можете дозволити ігровій дошці знати, яку частину ви хочете рухати, а потім вона сама впорядковує рух шматка, а шматок потім рухається в потрібному напрямку. Ця архітектура спрощує тестування кожного фрагмента коду в різних шарах, а потім дозволяє проводити тестування одиниць, інтеграцію та функціональне тестування.

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

Дякуємо за прочитане! =)


2
Це дуже схоже на контролер Model View.
tenpn

Якщо чесно, будь-який опис абстрагування інтерфейсу від основної реалізації буде звучати як Model View Controller. Але це тому, що використовувана термінологія та методики однакові (відсторонення від деталей реалізації та відокремлення інтерфейсу користувача від реалізації). Але це передбачає дуже просте середовище. Тут є кілька шарів, і в кожному шарі є контролери. Окремого виду від моделі тут недостатньо, потрібно також відокремити контроль взаємодії користувача від ігрового управління.
MrCranky

Цікаво, що тут такого складного, оскільки ми переміщуємо фрагменти головоломки на розмежувану ігрову дошку. Елементи управління отримані з графічного інтерфейсу, що є хорошим способом, і передаються на абстракційний шар, тобто в ігровий контролер. Контролер гри перевіряє на зіткнення при русі, потім повідомляє фігурі рухатися, якщо не виявлено зіткнення. Потім фрагмент головоломки належним чином рухається до потрібного напрямку та виявляє нове положення через Positionфункцію отримання властивостей, так що тепер ігровий контролер вимагає від GUI відобразити цю переміщену частину до нової позиції.
Буде Маркуйлер

хе, я блогував про "MVC" в розробці гри кілька місяців тому. Так, це хороша концепція шлюзу для тих, хто не ознайомився
Joel Martinez

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