Как я могу легко реализовать свинг в платформерной игре?

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;
Ali1S232
источник
Относится (к изготовлению веревки): 2D обнаружение столкновения веревки
двойник
@JonathanHobbs ответ на этот вопрос именно так, как я пытаюсь реализовать мою веревку с одним исключением, так как столкновение нежелательно в моем случае, я установил каждую часть веревки в качестве датчика, чтобы они могли свободно перемещаться, не застрять друг в друге.
Ali1S232
А как насчет простого маятника для веревки + некоторые анимации, которые появляются на веревке? Я не верю, что в старых играх, таких как Bionic Commando, было что-то еще, кроме маятника.
user712092
@ пользователь, что идея маятника должна работать нормально. но в моем случае, из-за быстрого движения игрока или плохой реализации, это не дало хороших результатов.
Ali1S232
@Gajet попробуйте сделать отладочный чертеж, пока вы не поймете это правильно? Эта линия маятника может быть выполнена в Box2D как достаточно тонкая коробка для столкновений (и, возможно, исключить ее из физики и перемещать вручную?).
user712092

Ответы:

6

Если вам нужно жесткое колебание, чтобы расстояние до точки вращения было постоянным, просто обработайте символ как точку на окружности с центром в точке вращения. Дайте ему одномерную (по кругу) угловую скорость. В каждом кадре угловое ускорение должно быть accelerationDueToGravity * cos(angleOfPlayerOnCircle)(с направлением 0 градусов вправо).

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

BlueRaja - Дэнни Пфлугхофт
источник
ваш ответ был моей второй попыткой, но он движется с гораздо большей скоростью, чем если бы я отредактировал свой вопрос и добавил свой код, возможно, вы сможете определить, в чем проблема.
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, но это не рекомендуется.

Ali1S232
источник
почему не так с box2d, чтобы заработать понижательную оценку ??
Ali1S232
Это не отвечает на вопрос. По крайней мере, напишите, как вы сделали это с помощью Box2D.
bummzack
@bummzack: хорошо, я добавлю это к своему ответу
Ali1S232
Если вы примете это как ваш ответ, ваш вопрос, если ошибаются. Физика сегментированных веревок сильно отличается от того, что вы описали.
AttackingHobo
@attackingHobo: в то время задание было правильным, но когда я преобразовал свой код в box2d, я понял, что без особых усилий я смог реализовать физику сегментированных веревок. и это не сильно отличается, подумайте о моем вопросе как об одном сегменте сегментированной веревки. и почти во всех моих решениях были способы реализовать веревку в стиле круга без box2d.
Ali1S232
2

Рассматривали ли вы возможность замедления скорости поворота, основываясь на том, как далеко верёвка находится от отвеса (центра)?

Рэндольф Ричардсон
источник
для всех трех подходов длина каната является одним из параметров, которые я использовал для расчета скорости качания. Но я не могу гарантировать, что я использовал это правильно. Я только что сделал некоторые физические вычисления и применил их решенную версию к игре.
Ali1S232
Чем дальше от центра, тем дольше задержка перед следующим движением качания каната. Вы также можете умножить значение задержки ABSolute примерно на 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;
AttackingHobo
источник
так что код, который я отредактировал в вашем ответе (извините за это, но я не нашел лучшего места, чтобы добавить его) тот, который вы предлагаете?
Ali1S232
Я одобрил редактирование, и да, я думаю, что так и должно быть. Хотя я и раньше использовал физику веревок и использовал гораздо более замысловатый способ сделать то же самое, из-за этого я не совсем уверен, что этот код будет работать должным образом, но я думаю, что он должен, и даже если это не так, он заставляет вас 95 % пути туда.
AttackingHobo
после некоторых попыток, я думаю, я попробую box2d для этой проблемы, и, кстати, вы должны изменить этот код, чтобы у вас было dx = player.x - attachpoint.xи dy = player.y - attachpoint.y.
Ali1S232
1

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

Кроме того, приведенная выше ссылка на вопрос «Веревка» является моей, и приведенная выше демонстрация действительно помогла.

Джои Грин
источник