GameMaker: Перетягивание вида/камеры

vis-view-drag

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

Animated demonstration for a tutorial on making click-and-drag views in GameMaker

Реализация

Реализация является довольно простой:

В начале нужно задать переменную для обозначения того что вид сейчас перетаскивают. Событие создания Create - неплохое место для этого:

dragging = false

После нужно событие, что непосредственно запускало бы процесс перетаскивания. Для этого подходят глобальные события мыши Global Mouse Left Pressed или Global Mouse Middle Pressed:

dragging = true
drag_x = mouse_x
drag_y = mouse_y

drag_x и drag_y пока что не имеют назначения, но они будут указывать "точку отсчета" для перетаскивания. Об этом я расскажу немного ниже.

Пожалуй, наиболее важной частью всей системы является код обновления. Он вставляется в любое из трех событий шага (Step):

if (dragging) {
    // непосредственное перетягивание:
    view_xview = view_xview + drag_x - mouse_x
    view_yview = view_yview + drag_y - mouse_y
}

Тут мы проверяем, перетягивают ли сейчас вид, и если это так, меняем его положение соответственно. Формула проста и неоднозначна - новое смещение вида определяется сложением разницы между изначальной и текущей позицией мыши с текущей позицией вида/камеры. Это работает поскольку mouse_x и mouse_y изначально включают смещение вида в своем значение. То есть, на самом деле формула выглядит где-то так "за кадром" (тут, _mouse_* обозначают координаты мыши относительно точки перетягивания и вида соответственно):

    view_xview = drag_xview + drag_mouse_x + view_xview - view_xview - view_mouse_x
    view_yview = drag_yview + drag_mouse_y + view_yview - view_yview - view_mouse_y

После сокращения само-уничтожающегося view_xview - view_xview, формула становится немного понятнее:

    view_xview = drag_xview + drag_mouse_x - view_mouse_x
    view_yview = drag_yview + drag_mouse_y - view_mouse_y

То есть, в эссенции, мы просто складываем разницу между старой и новой позицией мыши в виде с изначальной позицией самого вида. Смена знаков в формуле (+ mouse_x - drag_x) дала бы нам "обращенный" эффект перетягивания, что так же имеет свои применения, но это вы можете проверить и сами.

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

dragging = false

Другие полезности

"Не покидайте периметр"

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

if (dragging) {
    // непосредственное перетягивание:
    view_xview = view_xview + drag_x - mouse_x
    view_yview = view_yview + drag_y - mouse_y
    // убеждаемся что вид не покидает комнату:
    view_xview = max(0, min(view_xview, room_width - view_wview))
    view_yview = max(0, min(view_yview, room_height - view_hview))
}

Моноблок

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

// начало:
if (mouse_check_button_pressed(mb_left)) {
    drag_x = mouse_x
    drag_y = mouse_y
}
// обновление:
if (mouse_check_button(mb_left)) {
    // непосредственное перетягивание:
    view_xview = drag_x - (mouse_x - view_xview)
    view_yview = drag_y - (mouse_y - view_yview)
    // убеждаемся что вид не покидает комнату:
    view_xview = max(0, min(view_xview, room_width - view_wview))
    view_yview = max(0, min(view_yview, room_height - view_hview))
}

Загрузки

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

Скачать GMK

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

GameMaker: Перетягивание вида/камеры: 2 комментария

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

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