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: Перетягивание вида/камеры: 5 комментариев

  1. Ну, в этой статье как бы не указанны 70 процентов настроек параметров, без которых все это просто не будет работать…

  2. Интересует как добиться качественной работы подобной камеры на смартфонах. Не хватает инерции и некоторой интерполяции. Если двигать вид мышкой все хорошо, а вот пальцем – многое надо дорабатывать.

    • Инерцию делают, замеряя последнюю разницу координат до отжатия, и применяя это потом как скорость (я на это ранее отвечал под английской версией).

Добавить комментарий для Владимир Отменить ответ

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.