Как заставить персонажа прыгать?

45

В настоящее время я делаю игру на C #, используя Direct X 9.0. Римейк игры Donkey Kong NES. Я почти все закончил, но у меня проблемы с физикой прыжка Марио. У меня есть переменные, объявленные для координат Y и X.

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

В настоящее время у меня установлена ​​переменная bool, чтобы проверить, была ли нажата кнопка W, и это вызовет любой код, который заставит его прыгнуть. Я возился, например.

  if (jump == true)
    {

        Playerypos -=  vel;
        Playerxpos +=  vel;
    }

Который не работал так хорошо. Я искал ответ все выше и ниже, и теперь я в отчаянии, если кто-то может указать мне правильное направление на простое решение. Это было бы прекрасно. Очень ценю за любые ответы.

Сара
источник
5
Ответы, использующие другой язык программирования, не должны создавать проблем. Интересует алгоритм, а не конкретная реализация ... если только вы не надеетесь копировать и вставлять, ничего не понимая, чего я, безусловно, надеюсь, что вы не понимаете! Умение читать и адаптировать алгоритмы из других языков программирования - очень хороший навык.
ccxvii

Ответы:

85

Прежде всего, XNA также использует C #, так что это тот же язык программирования. И хотя базовый API может иметь некоторые отличия от DirectX, это не имеет никакого отношения к прыжкам, поэтому здесь должны применяться те же учебники или ответы. Кроме того, существует множество способов реализовать это в зависимости от множества факторов. То, что я опишу ниже, является лишь одной из возможностей.

Основные физические требования

Для начала вам понадобятся базовые физические переменные и расчеты в цикле обновления. В частности, вам нужно определить положение, скорость и гравитацию, и ваш цикл обновления должен делать что-то похожее на это (обнаружение столкновений и реакция для простоты опущены):

float positionX, positionY;     // Position of the character
float velocityX, velocityY;     // Velocity of the character
float gravity = 0.5f;           // How strong is gravity

void Update(float time)
{
    positionX += velocityX * time;      // Apply horizontal velocity to X position
    positionY += velocityY * time;      // Apply vertical velocity to X position
    velocityY += gravity * time;        // Apply gravity to vertical velocity
}

Фиксированный прыжок в высоту

Теперь самый простой способ осуществить прыжок, который всегда имеет одинаковую высоту, независимо от того, как долго вы нажимаете клавишу, - это просто изменить вертикальную скорость один раз. Это заставит персонажа начать расти, а гравитация автоматически позаботится о его падении:

void OnJumpKeyPressed()
{
    velocityY = -12.0f;   // Give a vertical boost to the players velocity to start jump
}

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

Переменная высота прыжка

Но игры, такие как Mario и Sonic, имеют переменный прыжок, где высота прыжка зависит от того, как долго вы нажимаете кнопку. В этом случае вам нужно обрабатывать нажатие и отпускание клавиши перехода. Вы можете добавить что-то вроде:

void OnJumpKeyReleased()
{
    if(velocityY < -6.0f)       // If character is still ascending in the jump
        velocityY = -6.0f;      // Limit the speed of ascent
}

Подстройка всех этих значений (то есть числа , как 0.5, -12.0fили -6.0f) в коде выше вы можете изменить вид вашего прыжка, как высоко он подскакивает, сколько импульса он держит даже после отпускания кнопки прыжка, как быстро он падает, и т.д. ,

Важно Не вызывайте эти функции каждый кадр. Вызывайте их только один раз, когда клавиша нажата или отпущена. В противном случае ваш персонаж будет летать вместо прыжка.

Рабочий пример

Я только что создал краткий пример техник, описанных выше, которые вы можете попробовать в своем браузере здесь (нажмите кнопку мыши, чтобы прыгать, отпустите ее на полпути, чтобы контролировать высоту прыжка). Это в JS, но, как я упоминал ранее, язык в данном случае не имеет значения.

http://jsfiddle.net/LyM87/

Дэвид Гувея
источник
11
Можно также воспользоваться возможностью поделиться этой удивительной статьей, написанной несколько дней назад, с информацией, связанной с этой темой: Руководство по реализации 2D-платформеров . А также это: Sonic Jumping .
Дэвид Гувея
2
В статье описан другой способ выполнения переменных прыжков, чем вы сделали в своем ответе. Он требует подавления гравитации или продолжения добавления импульса при удержании кнопки. Я обычно делаю то, что говорит Дэвид в своем ответе, но есть ли какие-нибудь мысли по поводу методов статьи?
Джефф
@Jeff Это также привлекло мое внимание, и именно поэтому я упомянул, что есть несколько способов реализовать это. Первая статья описывает два дополнительных способа решения той же проблемы, в то время как описанный мной способ основан на второй статье. Я не знаю, как они сравниваются друг с другом, хотя любой из них довольно легко реализовать. В конце концов, я выбрал этот метод, потому что его было проще объяснить, и он не требовал добавления таймера или работы с несколькими импульсами уменьшающихся величин.
Дэвид Гувейя
Ответ может варьироваться в зависимости от конкретной игры и количества анимаций, которые вы хотите сделать. Metroid использует прыжок с постоянной скоростью: / спуск, но маскирует его высококачественной анимацией, чтобы он выглядел гладким и «изогнутым» в зените. Многие другие платформеры используют скачки с переменной скоростью, которые требуют больше работы, чтобы заставить его работать хорошо.
Шон Мидлдитч
1
это было очень полезно, 5 лет спустя :) и эта скрипка очень крутая - я должен выучить JS!
Текучесть
1

Как в физике. Только в тот момент, когда вы нажимаете, jump keyи персонаж на земле прибавляет скорость вверх (это называется импульсом), но заставляет персонажа падать под действием силы тяжести все время.

Если Вы не хотите, чтобы персонаж прыгал каждый раз, когда он ударяется о землю - потому что Вы держите jump key- добавьте jump key is being pressedпеременную, которую Вы очищаете после jump key, отпускается и устанавливается после. псевдокод:

if jump being key pressed == false && jump key just pressed
   add y velocity 
   jump being key pressed = true

if jump key released
   jump being key pressed = false

decrease velocity by gravity
check for collisions // to not penetrate ground ...

Если бы я использовал Твой путь:

if jump key not pressed
     jump height = 0            // imaginary height donkey would travel without gravity

if jump key pressed
     // going up
     if jump height < maximal height donkey might jump
         jump height += 5
         donkey.y    += 5        // 
     // going down
     else if jump height < 2 * maximal height donkey might jump
         jump height += 5
         donkey.y    -= 5

Как donkey.yизменится, зависит от вашего воображения. Скорость должна становиться меньше. Осел в воздухе, чтобы он выглядел хорошо.

user712092
источник