Сегодня я немного расскажу вам про реализацию эффекта "перетягивания камеры" в 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х событиях).
Ну, в этой статье как бы не указанны 70 процентов настроек параметров, без которых все это просто не будет работать…
Интересует как добиться качественной работы подобной камеры на смартфонах. Не хватает инерции и некоторой интерполяции. Если двигать вид мышкой все хорошо, а вот пальцем — многое надо дорабатывать.
Инерцию делают, замеряя последнюю разницу координат до отжатия, и применяя это потом как скорость (я на это ранее отвечал под английской версией).
Ссылка не работает!
Исправил.