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


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.