Це питання - це "наступне" питання з попереднього мого питання щодо виявлення та вирішення зіткнень, яке ви можете знайти тут .
Якщо ви не хочете читати попереднє запитання, ось короткий опис роботи мого фізичного двигуна:
Кожна фізична особа зберігається у класі, який називається SSSPBody.
Підтримуються лише AABB.
Кожен SSSPBody зберігається у класі під назвою SSSPWorld, який оновлює кожне тіло та обробляє гравітацію.
Кожен кадр, SSSPWorld оновлює кожне тіло.
Кожне оновлене тіло шукає довколишні тіла в просторовому хеші, перевіряє, чи потрібно їм виявляти зіткнення з ними. Якщо так, вони викликають подію "зіткнення" і перевіряють, чи потрібно їм вирішувати зіткнення. Якщо так, вони обчислюють вектор проникнення та напрямне перекриття, а потім змінюють своє положення, щоб вирішити проникнення.
Коли тіло стикається з іншим, воно передає свою швидкість іншому, просто встановлюючи швидкість тіла на власну.
Швидкість тіла встановлюється на 0, коли воно не змінило положення з останнього кадру. Якщо він також стикається з рухомим тілом (наприклад, підйомником або платформою, що рухається), він обчислює різницю руху підйомника, щоб побачити, чи кузов не перемістився з останнього положення.
Також тіло викликає "розчавлену" подію, коли всі його кути AABB перекривають щось у кадрі.
Це ПОВНИЙ вихідний код моєї гри. Він розділений на три проекти. SFMLStart - це проста бібліотека, що обробляє введення, малювання та оновлення об'єктів. SFMLStartPhysics є найважливішим, де є класи SSSPBody та SSSPWorld. PlatformerPhysicsTest - ігровий проект, що містить всю логіку гри.
І це метод "оновлення" у класі SSSPBody, коментований та спрощений. Ви можете поглянути лише на це, якщо вам не здається дивитися на весь проект SFMLStartSimplePhysics. (І навіть якщо ви це зробите, то все одно слід поглянути на це, оскільки це коментується.)
.Gif показує дві проблеми.
- Якщо тіла розміщені в іншому порядку, трапляються різні результати. Ящики зліва ідентичні ящикам праворуч, розміщеним лише у зворотному порядку (у редакторі).
- Обидва ящики повинні рухатись у верхній частині екрана. У ситуації з лівого боку ящики не приводяться в рух. Праворуч - лише одна з них. Обидві ситуації є ненавмисними.
Перша проблема: порядок оновлення
Це досить просто зрозуміти. У ситуації, що знаходиться зліва, верхня ящик оновлюється перед іншою. Навіть якщо ящик на дні "передає" швидкість іншому, йому потрібно почекати наступного кадру, щоб переміститися. Оскільки він не рухався, швидкість нижньої обрешітки встановлюється на 0.
Я не маю уявлення, як це виправити. Я вважаю за краще рішення не залежати від "сортування" списку оновлень, тому що я думаю, що я роблю щось не так у всій конструкції двигуна фізики.
Як основні фізичні двигуни (Box2D, Bullet, Бурундук) обробляють порядок оновлення?
Друга проблема: у напрямку до стелі приводиться тільки один ящик
Я ще не розумію, чому це відбувається. Те, що робить "пружинне" утворення, - це встановити швидкість тіла до -4000 і переставити його поверх самої пружини. Навіть якщо я відключую код перепозиціонування, проблема все одно виникає.
Моя ідея полягає в тому, що коли нижня обрешітка стикається з верхньою ящиком, її швидкість встановлюється на 0. Я не знаю, чому це відбувається.
Незважаючи на шанс виглядати як хтось, хто здається при першій проблемі, я розмістив весь вихідний код проекту вище. У мене немає нічого, щоб довести це, але повірте, я дуже намагався це виправити, але просто не міг знайти рішення і не маю попереднього досвіду роботи з фізикою та зіткненнями. Я намагаюся вирішити ці дві проблеми більше тижня, і зараз я в розпачі.
Я не думаю, що я можу знайти рішення самостійно, не знімаючи з гри багато функцій (наприклад, швидкість передачі та пружини).
Велике спасибі за витрачений час на читання цього питання, і ще більше дякую, якщо ви навіть спробуєте знайти рішення чи пропозицію.