Гравитация с воздушным временем, ускорением и набором скорости



Я пытаюсь создать гравитацию, включая эфирное время, а также ускорение.
Я пробовал использовать обычную гравитацию, которая выглядит примерно так:

velocity += gravity * dt;
position += velocity * dt;


Это, вероятно, подойдет для обычной игры-платформеров, но я пытаюсь создать игру, вдохновленную «игрой с вертолетом», где вам нужно перемещаться по туннелю, не касаясь стен.

Что я хочу сделать по-другому, так это то, что я хочу иметь возможность сохранять скорость на спуске, которая будет использоваться снова на пути вверх, поэтому у меня будет некоторое ускорение в начале.
Я также хочу своего рода эфирное время, поэтому, когда вы попадаете на вершину, это не заставит вас опускаться так быстро, как это было бы, если бы я использовал гравитацию из примера кода.

Это изображение иллюстрирует кривую, которую я хотел бы :
Ссылка на кривую

Обратите внимание, что все управление осуществляется одной кнопкой, поэтому например, вы взлетите, если удерживаете пробел, и нырнете, если отпустите его.
Персонаж также никогда не двигается влево или вправо, так как он будет иметь статическое положение X на экране, поэтому векторы нельзя использовать .

Я часами пытался кей это работает, но безуспешно. Я также пробовал искать в Интернете, но безуспешно.

Игра "Whale Trails" получила ту гравитацию, которую я хотел.
Вот ссылка на видео игры: http://www.youtube.com/watch?v=5OQ0OWcuDJs

Я не такой уж большой физик, поэтому было бы здорово, если бы вы могли привести пример реального кода - надеюсь, кто-нибудь поможет мне разобраться в этом.


person Basic    schedule 24.11.2011    source источник
comment
Неплохой вопрос, но показ кода, который иллюстрирует то, что вы пробовали, и описание того, как это не работает, поможет вам получить ответы. :)   -  person Dan J    schedule 25.11.2011
comment
Я тоже не физик, но полагаю, что вам нужно углубиться в физику, чтобы добиться того, чего вы хотите. Так что я думаю, что физика самолетов должна быть в общем направлении. Может быть, это поможет вам хотя бы немного найти правильные слова для поиска для решения вашей проблемы. Также в новейшей игре Batman - Arkham City Game есть похожая механика, которую, возможно, стоит проверить.   -  person dowhilefor    schedule 25.11.2011
comment
@djacobson в основном это был случайный код, так как я понятия не имел, куда идти, так что толку от этого не было :)   -  person Basic    schedule 25.11.2011
comment
@dowhilefor Вы, наверное, правы, но было бы неплохо, если бы для этого уже был какой-то код;)   -  person Basic    schedule 25.11.2011
comment
В игре Whale Trails кажется, что горизонтальная скорость меняется, даже если кит остается в том же положении на экране. Прокрутка экрана ускоряется и замедляется. Похоже, вам нужно будет использовать 2D-вектор, чтобы воспроизвести это поведение.   -  person JohnPS    schedule 26.11.2011


Ответы (3)


Гравитация - это сила, притягивающая предметы вниз. Ваш игрок - это сила, которая поднимает предметы. Соответственно ваш код должен быть:

if(keyPressed) {
  velocity += POWER_OF_PLAYER;
}

velocity += G;
position += velocity;

Этого достаточно, чтобы создать кривую, как вы проиллюстрировали. Конечно, POWER_OF_PLAYER должен иметь другой знак, и абсолютное значение должно быть больше, чтобы это работало.

G = -9.81
POWER_OF_PLAYER = 20

Тогда простая проверка - это экономия энергии.

if(keyPressed) {
  if(powerSaved > 0) {
    velocity += POWER_OF_PLAYER;
    powerSaved -= SOMETHING;
  }
} else if (velocity >= SOME_MINIMUM_SPEED_BEFORE_GETTING_POWER) {
  powerSaved += SOMETHING;
}

SOME_MINIMUM_SPEED_BEFORE_GETTING_POWER должно быть меньше или равно 0.

P.S. Я предположил, что ваша ось Y начинается с земли и устремляется в небо. Знаки ставим соответственно.

person Marcel Jackwerth    schedule 25.11.2011
comment
Я почти уверен, что пробовал это, но я попробую с вашим кодом и посмотрю, работает ли он :) - person Basic; 25.11.2011
comment
Это стандартная формула, физика в игре другая. - person Klas Lindbäck; 25.11.2011
comment
Ваша математика неверна. Гравитация - это сила, т. Е. Она имеет единицы массы * ускорение, в то время как скорость имеет единицы расстояния во времени, поэтому установка velocity += GRAVITY в корне неверна. - person rcollyer; 09.12.2011
comment
@rcollyer Переменная должна быть названа G или STRENGTH_OF_THE_GRAVITATIONAL_FIELD (которая не зависит от массы и эквивалентна ускорению объекта под действием силы тяжести), чтобы исправить это, или мы должны предположить, что все массы в этой системе равны единице. t опровергнуть остальную часть ответа. - person Marcel Jackwerth; 09.12.2011
comment
Да, при условии, что масса 1 кг, это близко. Вам все равно нужно умножить G на приращение времени, чтобы получить правильные единицы, то же самое с Power_Of_Player, при условии, что это также сила. - person rcollyer; 10.12.2011

Похоже, скорость рыбы постоянна.

Попробуйте следующее:

velocity исправлен и не должен меняться (если рыба не съедает ускорение). angle = 0 эквивалентно горизонтальному полету.

angle -= gravity * dt;
if (angle < - Math.PI / 2) {
  angle = Math.PI / 2;
}
if (keyPressed) { 
  angle += power * dt;
}

if (angle < - Math.PI / 2) {
  // Stop the player from doing a looping
  angle = - Math.PI / 2;
}
if (angle > Math.PI / 2) {
  // Stop the player from doing an inverted looping
  angle = Math.PI / 2;
}
// Move the fish (vertical component of velocity)
position += velocity * dt * Math.sin(angle);
// Move the background (horizontal component of velocity)
background_position -= velocity * dt * Math.sin(angle);
person Klas Lindbäck    schedule 25.11.2011
comment
При использовании вашего кода проигрыватель просто идет прямо, если только при нажатии клавиши он не опускается немного вниз. - person Basic; 26.11.2011
comment
Попробуйте сделать изменения угла меньше - angle -= gravity * dt / 100.0; и angle += power * dt / 100.0; - person Klas Lindbäck; 27.11.2011

Похоже на включение «подъема», основанного на горизонтальной скорости, и если бы нажатие кнопки запускало движение «нос вверх», это сработало бы достаточно хорошо.

Таким образом, lift будет некоторой константой k, умноженной на горизонтальную скорость Vx, а вертикальная скорость Vy будет разницей в gravity и lift раз изменения во времени dt

lift = k * Vx
Vy += ( lift - gravity ) * dt

def noseup
  k = 0.01 #some small chunk
  dx = k * Vx
  dy = k * Vy
  Vx -= dy
  Vy += dx

Когда самолет (или что-то еще) устремляется вверх, он снижает скорость по одной оси и увеличивает ее по другой.

Наверное, было бы неплохо бросить drag туда где-нибудь сейчас, когда я думаю об этом, должно было бы зависеть от абсолютной скорости _10 _... и вес в данном случае лучше, чем гравитация (менее запутанно , умные единицы), но я думаю, это работает.

Не совсем «физика», но близкое приближение, которое должно работать довольно хорошо. Поиграйте со значениями k и посмотрите, сможете ли вы заставить его делать то, что хотите.

Кстати, извините за дерьмовый псевдокод :-P

person Kyle G    schedule 26.11.2011