Як у 2D-ігровій платформі, як переконатися, що гравець плавно рухається по похилій землі?


18

Я розробляю двигун фізики для гри на 2D платформах. Я використовую теорему розділової осі для виявлення зіткнень. Наземна поверхня побудована з орієнтованих обмежувальних коробок, гравець як вісь, вирівняний обмежувальним ящиком. (Зокрема, я використовую алгоритм із книги "Виявлення зіткнення в реальному часі", який виконує розгорнуте зіткнення зіткнення для ОББ за допомогою SAT). Я використовую досить невеликий (близький до нуля) коефіцієнт реституції в реакції зіткнення, щоб гарантувати, що динамічні об'єкти не проникають у навколишнє середовище.

Двигун здебільшого працює чудово, я просто переймаюся деякими крайніми випадками, які можуть виникнути. Наприклад, на діаграмі A, B і C - земна поверхня. Гравець прямує ліворуч по В в напрямку А. Мені здається, що через неточність поле гравця може бути трохи нижче поля В, коли воно продовжується вгору та вліво. Отже, коли він досягне A, нижній лівий кут гравця може зіткнутися з правою стороною A, що було б небажано (оскільки гравець має намір плавно переміщатися над вершиною A). Схоже, подібна проблема може трапитися, коли гравець перебуває на полі С, рухаючись ліворуч у напрямку В - сама крайня точка В могла зіткнутися з лівою стороною гравця, замість того, щоб нижній лівий кут гравця ковзав вгору та вліво вище Б.

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

Будь-які пропозиції будуть дуже вдячні.


Загальний двигун фізики чудово підходить для ефектів і падаючих коробок і всього іншого, але не для фізики персонажів, як це викладено у розділі відповідей. Подумайте про те, щоб написати "статичну" фізику для свого персонажа, щоб ви могли на 100% контролювати та використовувати належну імітацію динаміки для решти.
Домі

Відповіді:


14

Платформинг та фізика

Ці крайові випадки численні. Хороші веселі платформи не ведуть себе фізично точно, а контроль та поведінку, на які гравці очікують через роки «ідеальних» платформерів, як Маріо, надзвичайно складно реалізувати із загальними методиками, такими як ви отримуєте з Box2D або іншими двигунами фізики. Більшість хороших платформерів не використовують будь-якої родової фізики чи реакції на зіткнення у своїх контролерах програвачів.

Створюють корпуси

Що стосується вашого конкретного питання, найкращим рішенням є припинення використання ящиків як вашої землі. Використовуйте ряд з’єднаних відрізків ліній (корпус). Це дозволяє двигуну виявлення зіткнень зосередитись лише на фактично поверхових поверхнях, а не дивитися на "підроблений" край, який існує між AB та BC. Саме це і робить Box2D. Форми використовуються для генерування зовнішніх поверхонь, які з'єднані між собою і утворюють корпус.

Це вам потрібно навіть в іграх на основі плитки або в ситуаціях, коли у вас є два об'єкти AABB поруч з іншими, що виступають в якості підлоги. Двигун зіткнення підхопить ці вертикальні кромки і призведе до того, що гравець зачепить їх. Є хаки, які можуть допомогти, але не усунути проблему. Рішення полягає в тому, щоб просто мати однорядний сегмент, що представляє поверхню, а не повний 2D-ящик.

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

Похилі поверхні

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

Друга проблема, яку ви помітите, яку набагато важче виправити, - це те, що відбувається, коли ви намагаєтесь швидко бігти по рампі. Гравець збирається "скакати" по рампі. Це дуже добре видно навіть у більшості ігор AAA сьогодні. Це не тільки виглядає нерозумно, але якщо ваша гра вимагає, щоб гравець тримався на землі, щоб стрибати, це ускладнює біг по рампі та стрибок на півдорозі, тому що гравець контактує з пандусом лише протягом невеликої частини час, витрачений на спуск. Більш просте виправлення полягає в тому, щоб просто зробити кілька випромінювань, коли гравець рухається, і перенести позицію гравця вниз до найближчої поверхні (якщо вона дуже близька до гравця), якщо гравець не стрибає і раніше був на землі.

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

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


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

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

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

@Kovsa: знову ж такі конкретні помилки зникають, коли ти позбудешся ребер, які не повинні в першу чергу бути частиною зіткнення. З’єднайте краї разом, щоб вийшла безперебійна форма. Створюючи свій рівень, я також рекомендую з'єднати вершини разом, щоб у вас не було невеликих щілин на поверхнях. Не відрізняється насправді, ніж те, як ви проектуєте рівень у 3D-редакторі сітки.
Шон Міддлічч

Хм ... я не думаю, що я слідую за цим. У моєму діаграмі, якщо я з'єднаю ребра разом, щоб зробити безперебійну форму, я отримав би форму, що складається з трьох лінійних сегментів: вершина коробок A, B і C, правда? Незважаючи на те, що це одна форма, мені все одно потрібно було б виявити зіткнення окремо проти лінії А, потім В, потім С, чи не так? Якщо ви не мали на увазі алгоритм, який може виявити зіткнення коробки та цієї комбінованої форми? Я припускаю, що тоді це не буде SAT, оскільки серія ребер може бути увігнутою?
Нік Ковач

5

Я думаю, що обидві проблеми можна було б вирішити, обробляючи ваші ящики для цілей реагування на зіткнення, як якщо б вони мали закруглені кути (аналогічного радіусу, як і вашої числової помилки). Це зробить ефективну комбіновану поверхню кутів для зустрічей між A і B та B і C більш гладкою.

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


Однак, більш типовим рішенням щодо перегляду того, що я знаю про фізику платформерів, є надання гравцеві більш сильно закругленої форми і залишити місцевість у спокої. Зокрема, подумайте про те, щоб зробити форму гравця капсулою (натягнуте середнє коло (2D) / сфера (3D)) - тоді ваші норми зіткнення будуть, природно, будуть майже вертикальними, усуваючи будь-які проблеми з ловом.

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


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

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

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

Ворота: D'oh! Гаразд, не так просто, як я думав.
Кевін Рейд

Так, після роздумів над цим капсульний підхід, мабуть, більше підходить для 3D-гри, а не для двовимірного платформи. Наявність ідеального керування пікселями для мене, безумовно, є пріоритетом (як це було у всіх тих старих 2D-платформерів). Але повинно бути рішення, яке дозволяє використовувати коробки!
Нік Ковач
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.