Прыгаем!

Гравитация - неотъемлимая часть всех игр, в которых надо куда-то идти/ехать/прыгать и т.д.
Фокус в том, что для того, чтобы добиться более-менее правдоподобного передвижения вашего героя по крайней мере в двух измерениях, было бы хорошо, если бы на него действовала некая сила вертикально вниз. Если вы попробуете хоть чуть-чуть вспомнить школьные уроки физики, то наверное вспомните, что такая сила называется гравитацией (aka Всемирным Тяготением !)

Так вот, представьте, что у нас имеется некий нарисованный индивидуум под кодовым именем Bob. Что этот Bob будет иметь в качестве параметров, задающих его существование в двухмерном мире? Правильно, координаты. А вот для того, чтобы успешно передвигаться, Bob должен иметь еще некую скорость в определенный момент времени. В двухмерном мире он может иметь скорость по оси x и по оси y. Итак, что получается? А получается такая вот структурка, заданная для того, чтобы научить Bob'а прыгать:

bob.pos.y=0;
bob.vel.y=0;
bob.jumping=NO;

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

С самого начала, Bob стоит на земле (pos.y=0) и его скорость по вертикали тоже равна нулю (vel.y=0)

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

Loop

If (кнопка прыжка нажата)
{
Bob.vel.y = 100;
Bob.jumping = YES;
}

if (Bob.jumping == YES) /* Если Bob в прыжке, то менять координаты*/
{
Bob.vel.y = Bob.vel.y - Bob.accel
Bob.pos.y = Bob.pos.y + Bob.vel.y
}

if (Bob.pos.y <= 0) /* Проверить, соприкоснулся ли Bob с землей*/
{
Bob.vel.y = 0;
Bob.jumping = NO;
}

End Loop

Если нарисовать этот цикл на бумажке, то получится, что координаты Bob'а изменяются так:

Loop0 : Bob.vel.y = 0 Bob.pos.y = 0
Loop1 : Bob.vel.y = 100 Bob.pos.y = 100
Loop2 : Bob.vel.y = 90 Bob.pos.y = 190
Loop3 : Bob.vel.y = 80 Bob.pos.y = 270
Loop4 : Bob.vel.y = 70 Bob.pos.y = 340
Loop5 : Bob.vel.y = 60 Bob.pos.y = 400
Loop6 : Bob.vel.y = 50 Bob.pos.y = 450
Loop7 : Bob.vel.y = 40 Bob.pos.y = 490
Loop8 : Bob.vel.y = 30 Bob.pos.y = 520
Loop9 : Bob.vel.y = 20 Bob.pos.y = 540

Loop10: Bob.vel.y = 10 Bob.pos.y = 550
Loop11: Bob.vel.y = 0 Bob.pos.y = 550
Loop12: Bob.vel.y = -10 Bob.pos.y = 540
Loop13: Bob.vel.y = -20 Bob.pos.y = 520
Loop14: Bob.vel.y = -30 Bob.pos.y = 490
Loop15: Bob.vel.y = -40 Bob.pos.y = 450
Loop16: Bob.vel.y = -50 Bob.pos.y = 400
Loop17: Bob.vel.y = -60 Bob.pos.y = 340
Loop18: Bob.vel.y = -70 Bob.pos.y = 270
Loop19: Bob.vel.y = -80 Bob.pos.y = 190
Loop20: Bob.vel.y = -90 Bob.pos.y = 100
Loop21: Bob.vel.y =-100 Bob.pos.y = 0

Самые догадливые наверняка заметят, что если вдруг земли не окажется на ее обычном месте в y=0, то Bob полетит дальше, причем вскоре его скорость станет такой, что и подумать страшно. Именно для этого надо ввести ограниченное ускорение. В реальном мире ускорение падающего человека ограничивает сопротивление воздуха. Мы же можеи просто указать какая скорость падения будет для Bob'а максимальной. Посмотрите на вот этот псевдо-код:

Bob.pos.y = 0; (Или где у вас там земля :)
Bob.vel.y = 0;
Bob.accel = 10;
Bob.jumping = NO;

Loop

if (кнопка прыжка нажата AND Bob.Jumping == NO)
{
Bob.vel.y = 100;
Bob.jumping = YES;
}

if (Bob.jumping == YES) /* Если Bob в прыжке, то менять координаты */
{
if (Bob.vel.y > -100) /* Ограничить скорость до -100 */
{
Bob.vel.y = Bob.vel.y - Bob.accel
Bob.pos.y = Bob.pos.y + Bob.vel.y
}
}

if (Bob.pos.y <= 0) /* Проверить, соприкоснулся ли Bob с землей */
{
Bob.vel.y = 0;
Bob.jumping = NO;
}

End Loop

Кроме ограничения скорости падения, я ввел отлов повторного нажатия клавиши прыжка, когда мы и так находимся в прыжке. В реальной практике программирования такие "мелкие" упущения будут всегда.

Однако наш Bob сможет дергаться только вверх-вниз, а многие игры, в основном аркады позволяют нам перемещаться в прыжке вперед-назад. Легко! Когда вы высчитали координату Y, куда попадет Bob, вы можете управлять его X координатой как сами захотите. Можно не реагировать в процессе прыжка на клавиши, двигающие Bob'а вперед-назад, а можно реагировать, давая возможность игроку управлять полетом. Но главное помните - для большей реалистичности, в прыжке сила противодействия должна действовать не только сверху, но и по горизонтали. Поэтому, на каждом шаге цикле прорисовки, если не нажата клавиша движения по горизонтали, уменьшайте горизонтальное ускорение так же, как и в случае с прыжком. Если позволяете герою двигаться в прыжке, пусть приращение скорости в воздухе будет меньшим, чем на земле.

Помните, реалистичная физика только украшает игру!

Приятного программирования, Antiloop

Posted: 28.01.2k1
Autor: Antiloop
<anti_loop@mail.ru>