GameMaker: Эффекты скольжения окна

Window sliding example for GameMaker

Эта запись посвящена созданию эффекта аналогичного используемого в моей старой программе GMConveter. Вообще-то сама по себе программа была в некоторой степени шуткой, так как в момент ее выпуска единственная разница между файловыми форматами GM80 и GM81 была байтом версии в заголовке, который ей собственно и изменялся, делая файлы вновь совместимыми. Довольно неплохо для чего-то что было скачано более 4000 раз за два года, правда?
Помимо внутренней простоты программа так же имела неплохой внешний вид, включая эффект плавного скольжения окна. Об этом я и расскажу.

Основы

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

slide_from = display_get_height() - 1 // скольжение с нижнего края экрана
slide_to = window_get_y() // конечная координата
slide_now = 0 // позиция (0..1)

И немного кода для непосредственного передвижения окна (идет в событие шага):

slide_now = min(slide_now + 0.02, 1)
window_set_position(window_get_x(),
    slide_from + slide_now * (slide_to - slide_from))

Если вы запустите код на этом моменте, вы увидите окно, выезжающее снизу экрана где-то так:

Window sliding example for GameMaker. Demonstration (linear interpolation)

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

Делаем процесс "интересным"

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

Window sliding example for GameMaker

После этой небольшой замены событие шага будет выглядеть так:

slide_now = min(slide_now + 0.02, 1)
window_set_position(window_get_x(),
    slide_from + sin(slide_now * pi / 2) * (slide_to - slide_from))

И будет вести себя так:

Window sliding example for GameMaker. Demonstration (sinusoid)

Исправления и добавления

Одна заметная вещь с приведенным выше кодом заключается в том что игра появляется на изначальной позиции на момент после запуска (до начала скольжения). Это может быть исправлено копированием вызова window_set_position из шага в конец события создания. Или переносом его в пользовательское событие, например User Defined 0:

/// Обновляет положение окна
window_set_position(window_get_x(),
    slide_from + (slide_to - slide_from) * sin(slide_now * pi / 2))

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

slide_from = display_get_height() - 1 // скольжение с нижнего края экрана
slide_to = window_get_y() // конечная координата
slide_now = 0 // позиция (0..1)
slide_delta = 0.02 // скорость скольжения
event_user(0) // call first update

Ради оптимизации и обработки нововведений, событие шага так же подлежит нескольким изменениям:

if (slide_delta > 0) { // входящее скольжение
    if (slide_now < 1) {
        slide_now = min(slide_now + slide_delta, 1)
        event_user(0)
    }
} else { // выходящее скольжение
    slide_now += slide_delta
    if (slide_now <= 0) {
        // окно исчезает перед закрытием
        if (window_get_visible()) window_set_visible(0)
    } else event_user(0)
    // тут окно уже правда закрывается:
    if (slide_now < -1) game_end()
}

И, на последок, выходящая анимация как-то должна включаться, для чего неплохо подходит событие нажатия Escape (для правильной работы в GM<=8.1 нужно выключить автоматическое завершение игры в глобальных настройках):

/// начинать "ускальзывание", если еще не начато
if (slide_delta > 0) {
    slide_to = window_get_y() // убеждаемся что координаты не сломаны перемещением окна
    slide_delta = -abs(slide_delta) // устанавливаем скольжение в противоположном направлении
    slide_now = 1 // опять таки, убеждаемся что ничего не сломается
}

И, после всех этих изменений, у нас есть вполне хорошая модель скольжения, выглядящая так::

Window sliding example for GameMaker. Demonstration (fade-in, fade-out)

Вы можете так же скачать финальную версию с кодом выше для избежания "ошибок сборки":

Скачать GMK

Так же вы можете скачать временный файл, который я использовал для создания анимаций, включенных в эту запись.

Похожие записи

GameMaker: Эффекты скольжения окна: 2 комментария

    • Закомментировать первую строку в событии создания (…// slide in from bottom of screen) и поставить на ее место вторую (…// slide in from top of screen).

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *