Як я можу легко реалізувати гойдалки в ігровій платформі?


9

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

Ось код, який я написав для обчислення крутного моменту:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

Доречно (про виготовлення мотузки): 2D виявлення зіткнення мотузки
— doppelgreener

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

Що про простий маятник для мотузки + деякі анімації, які з'являються на мотузці? Я не вірю, що у старих іграх, таких як Bionic Commando, було щось інше, ніж маятник.
— користувач712092

@user, що ідея маятника повинна добре працювати. але в моєму випадку або через швидкий рух гравця або через погану реалізацію, це не дало хороших результатів.
— Ali1S232

@Gajet спробуйте зробити малюнок налагодження, поки ви не зрозумієте це правильно? Ця маятникова лінія може бути виконана як досить тонка скринька в Box2D, щоб отримати зіткнення (а може бути, виключити її з фізики та рухатись вручну?).
— користувач712092

Відповіді:


6

Якщо ви хочете жорстко розпалити, тому відстань до точки повороту є постійною, просто розглядайте персонажа як точку на колі, зосередженому в точці обертання. Надайте йому одновимірну (по колу) кутову швидкість. Кожен кадр повинен бути кутовим прискоренням accelerationDueToGravity * cos(angleOfPlayerOnCircle)(з 0-градусним вказівкою праворуч).

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


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

3

після багатьох спроб я пішов з box2d.

в цілому є два підходи до цього моделювання або, принаймні, я знайшов 2:

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

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

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

наступне, про що ви повинні турбуватися - це кількість повторень, які ви переходите до світового оновлення: для низького сегмента мотузки (можливо, максимум 8) не потрібно використовувати велике значення ітерації, можливо, 10/10, яке сам запропонував box2d Досить, але якщо ви збільшите кількість сегмента, наприклад, я спробував 30 сегментів, при малій кількості ітерацій ваша мотузка, здається, збільшить її довжину більше, ніж повинна, тому для вирішення цих ситуацій вам знадобиться лише 40/40 ітерацій.

після деякого тестування здається, що поле 2d розраховане на сцени з розмірами об'єктів від 0,1 до 10 м, а максимальний розмір, запропонований для великих сцен, становить приблизно 50мх50м. так що в основному вам потрібно масштабувати ваш об'єкт вниз, щоб відповідати цим параметрам. у моєму випадку я спершу спробував передати піксельні позиції безпосередньо до box2d, але здавалося, що існують певні обмеження швидкості, які заважають світу рухатись так швидко, як і слід, тому мені довелося масштабувати свою сцену близько 64 разів, щоб мати найкращі результати. хоча я не перевіряв себе, у box2d є деякі обмеження, які заважають тобі використовувати більші сцени. наприклад, у b2Setting.hфайлі є визначене значення, #define b2_maxTranslation 2.0fви можете змінити налаштування box2d, але це, здається, не рекомендується.


чому не так у box2d, щоб заробити мені знижку ??
— Ali1S232

Це не відповідає на запитання. Принаймні напишіть, як ви змусили це працювати за допомогою Box2D.
— bummzack

@bummzack: Ок, я додам це до своєї відповіді
— Ali1S232

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

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

2

Чи розглядали ви уповільнення швидкості руху повороту, виходячи з того, наскільки далеко мотузка знаходиться від підвісної лінії (від центру)?


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

Чим далі від центру, тим довше затримка перед наступним рухом мотузки. Ви також можете помножити значення ABS затримки на щось на зразок 0,28 (вам доведеться експериментувати з цим).
— Рендольф Річардсон

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

1

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

Коли мотузка прикріплена. Збережіть maxLengthзначення.

Кожне оновлення, перевірте distanceміж і playerтаattachPoint

Якщо distanceнорма менше, ніж maxLengthоновлення нормально, жодних ефектів від мотузки немає.

Якщо відстань більша за величину maxLength, знайдіть гравець normalвід « attachPointдо». Отримайте різницю між distanceі maxLength. Додайте до playerVelocity, normalпомноженому на різницю.

Псевдокод:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

так це код, який я відредагував у вашій відповіді (вибачте за це, але я не знайшов місця, де краще його додати) той, який ви пропонуєте?
— Ali1S232

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

після деяких спроб я здогадуюсь, я спробую box2d для цього питання, і, до речі, ви повинні змінити цей код, щоб у вас є dx = player.x - attachpoint.xі dy = player.y - attachpoint.y.
— Ali1S232

1

Якщо подивитися на http://www.cocos2d-iphone.org/archives/1112 там є реалізація мотузки з жорстким тілом, прикріпленим до кінця мотузки. Він використовує Box2D для двигуна фізики. Якщо ви подивитеся на вихідний код, я впевнений, що ви можете його реалізувати будь-якою мовою.

Крім того, наведене вище посилання на питання щодо канату є моїм, і ця демонстрація (надана посилання) вище справді допомогла.

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