Продолжаем...
Процедурная анимация - довольно интересная штука, и у меня куча идей, что можно показать и анимировать... но не хватает времени на банальный набор текста здесь, в блоге.
Сегодня добрался до клавиатуры, и мы делаем прыгающий мячик! (исходники здесь)
Если честно, то я давно хотел такое в свой арсенал. Было интересно, как можно простенько сделать сжатие при касании земли и растяжение в полете. Как оказалось - без математики не обойтись. Но мы, уверен, не боимся её после первого поста :)
Как прыгает мяч по-настоящему
Если коротко, то движение мяча можно показать на "параболе рожками вниз". Например, вот так:красный, у=-(x-1)^2+1 |
"Оу, графики??" - удивитесь вы. А я отвечу - "да, иногда и графики бывают нужными, сегодня как раз такой случай" :) Но только не смотрите на функцию под графиком (я её привел просто так, чтобы всё было по-честному). Нам эта функция вообще не понадобится... в общем, продолжаем.
Итак, сначала объект двигается вверх, там немного повисел, притяжение планетой стало заметно, и тело устремилось вниз. Уверен, все помнят это из школы. Выглядит это приблизительно так:
Я использую такой метод часто, но не для цикличных движений. То есть кинуть что-то один раз - отлично, двигаемся по параболе. Но, если мне нужен отскакивающий много-много раз мячик (и особенно с дополнительным расплющиванием внизу) - то обычной параболой здесь не обойтись...
Как мы будем подбрасывать мяч
Где цикличность - там и синусы/косинусы. Представляю вашему вниманию абсолютное значение (в школах еще говорят "модуль") от синуса:синий, y=abs(sin(x*pi/2)) |
Как мы видим, он ну прям очень похож на параболу. При этом цикличное движение выходит само по себе, и это отлично!
Сжатие внизу
Да, но обычное вверх-вниз движение выглядит очень деревянным и зажатым. Нам нужно больше экспрессии. Давайте думать, как это реализовать...Сделаем следующий трюк. Смотрите, если немного поднять землю, то наш мячик будет какое-то время как будто под землей, вот так (на гиф я замедлил движение, чтобы лучше разглядеть):
Теперь, будем сжимать по вертикали спрайт так, чтобы его нижняя сторона всегда оставалась на земле, визуально не проваливаясь.
Ок, с масштабом по вертикали еще более-менее понятно, а как при этом растягивать мячик по горизонтали? Не вдаваясь в математику (идея в сохранении площади эллипса) скажу, что произведение масштабов оставляют прежним. То есть scale.x * scale.y = 1 всегда. Ок, попробуем:
Растяжение в полете
Вот здесь у меня был самый большой затык. Штука в том, что растяжение должно выглядеть естественным и при этом равномерным при движениях вверх и вниз. Проблема в том, что синус довольно быстро нарастает, а мне, наоборот, нужна пауза перед нарастанием. В таком случае я придумал применить степень от синуса, например, четвертую:Снова масштаб по горизонтали меняем как scale.x = 1 / scale.y:
Ура! Немного математики и мячик ожил!
Полировка
И вроде всё хорошо. Но не до конца... Смотрите, как на последней гифке мячик очень мало времени проводит внизу сжимаясь-разжимаясь. (конечно, тут еще гиф съедает кадры) Хочется, чтобы он там чуточку задержался, давая взгляду возможность всё понять.Для этого немного схитрим и изменим наш изначальный синус (для движения вверх-вниз). Возведем его в степень, и это позволит чуть быстрее падать, но при этом немного задерживаться внизу. Смотрим результат:
Итоговый код
Мне понравилось выкладывать исходники на WonderFL. Наглядно, просто, удобно.Итого
Процедрные анимации, зачастую, несут много математики и требуют множества экспериментов. "В чем же тогда бонус всего этого барахла?" - спросите вы. Красота такого кода в легкой, быстрой и понятной настройке движений мячика. Можем изменить высоту прыжка, силу "расплющивания", время в нижней точке и многое другое... при этом общий стиль движения нашего мяча останется неизменным.Вот пример двух констант (из исходников) и их влияния на движение:
На этом всё... процедурного всем счастья!
0 коммент.:
Отправить комментарий