Привет!
Сегодня разберёмся, как работает GUI, чем отличается от простого события рисования, как его настраивать и как с ним взаимодействовать.
Если возникнут вопросы - буду рад ответить в комментариях.
Напоминалка для запросившего пост: @Veslo7601
План:
- Теория. Что такое GUI?
- Практика.
- Как включить отрисовку GUI?
- Как удобнее использовать GUI?
- Зачем настраивать слой GUI и как?
- Как взаимодействовать с GUI?
- Как изменить курсор правильно?
Теория.
Что такое GUI?
GUI - графический пользовательский интерфейс, позволяющий взаимодействовать с программой (игрой) через графические элементы: иконки, меню, кнопки и т.п.
В GMS имеется два слоя, с которыми мы можем работать.
Первый зовётся application_surface. Это холст, на который происходит отрисовка любых форм в событиях draw, draw begin и draw end.
Второй - слой GUI, который рисуется выше, чем application_surface, перекрывая его. Отрисовка на него происходит, соответственно, в событиях draw GUI, draw GUI begin и draw GUI end.
Слой GUI по умолчанию равен размеру application_surface, который равен размерам комнаты. При этом, GUI автоматически подстраивается под размеры окна игры таким образом, чтобы вмещаться в него полностью.
"Глубина" (depth) работает точно также, как и на стандартном слое отрисовки. Чем меньше значение - тем "выше" рисуется объект. Если у объектов глубина одинаковая, то поверх будет рисоваться последний добавленный.
Практика.
Как включить отрисовку GUI?
Здесь всё просто.
Шаг первый.
У объекта создаём событие Draw (Рисовать) и внутри пишем одну команду:
exit;
Указанная функция говорит компилятору прекратить выполнение кода в данном событии, что немного оптимизирует игру.
Шаг второй.Создаём событие Draw GUI (Рисовать GUI) и внутри пишем
draw_self()
Либо любую другую команду отрисовки, которую хотите.
Как удобнее использовать GUI?
Располагать элементы интерфейса проще всего вручную. Самый простой способ - подстроить размер комнаты под предполагаемый размер GUI (либо настроить сетку под данные размеры) и расположить объекты там, где вам нравится. Про размер GUI будет чуть ниже.
Так как слой глубины (depth) на слое GUI работает точно также, как и на слое комнаты, имейте ввиду, что:
- При расположении объектов на одном и том же слое, перекрывать их будет тот объект, что поставлен последним. Настроить порядок создания объектов вы можете вручную. Для этого в комнате выделите слой с объектами и в инспекторе прокрутите до вкладки Instances. Все изменения будут отображаться в реальном времени, что удобно.
- Глубину можно настроить вручную в любом событии, кроме события отрисовки. Для этого есть переменная depth; помните, что чем меньше значение - тем выше рисуется объект.
К сожалению, вывести слой GUI на экран на подобие комнаты на данный момент нельзя и иных удобных способов работы с GUI нет. Впрочем, вы также можете работать с ним через код, но это не так наглядно и занимает больше времени.
Зачем настраивать слой GUI и как?
Слой GUI сделан таким образом, чтобы всегда вмещаться в размер дисплея/игрового окна или application surface. Как следствие, появляется масштабирование тех объектов, которые мы рисуем на данном слое, чтобы они соответствовали заданным параметрам.
Объекты, которые мы рисуем на слое GUI, по умолчанию будут масштабироваться в зависимости от размеров application_surface. Чтобы этого избежать нужно установить размер GUI вручную.
Для этого существует команда:
display_set_gui_size(широта, высота);
При этом стоит помнить, что GUI продолжает подстраиваться под размер окна. Соответственно, нам также нужно зафиксировать размер окна. Для этого существуют следующие команды:
window_set_size(широта, высота), либо включить полноэкранный режим: window_set_fullscreen(true);
После указанных действий картинки на экране и в редакторе будут одинаковыми. Главное помните, что масштабирование к размеру окна происходит в любом случае.
Дальше работать предстоит методом подбора. Я обычно выставляю размер GUI (1920x1080) и расставляю все элементы относительно указанных значений.
Размер масштабирования вы также можете настроить. Для этого существует команда:
display_set_gui_maximise(Масштабирование по X, масштабирование по Y, смещение по оси X, смещение по оси Y).
Простой вызов функции без аргументов приведёт к тому, что масштабирование будет вестись от позиции (0, 0) игрового окна с такой шириной и высотой, чтобы покрыть всё окно.
Такой способ может быть использован заместо display_set_gui_size в том случае, если размер окна и размер GUI, под который вы всё расставляли, одинаков. В ином случае лучше всё же воспользоваться display_set_gui_size();
Если указать (-1, -1), то произойдёт сброс до стандартных настроек. Т.Е. отрисовка будет вестись от позиции (0, 0) вашего application_surface и будет пытаться показать всю его область.
Другие значения приведут к масштабированию интерфейса в соответствии с заданными параметрами. (2, 2) = 200% по X и Y от размера игрового окна.
Как взаимодействовать с GUI?
Так как GUI рисуется на отдельном слое, нам понадобится использовать встроенные в движок функции, чтобы получить координаты мыши относительно этого слоя. Эти функции:
device_mouse_x_to_gui(0);
device_mouse_y_to_gui(0);
Соответственно, первая переводит координату X мыши в относительную к GUI, вторая - координату Y.
Так как это функции, рекомендую назначать в начале шага их локальным переменным, чтобы избежать постоянных перерасчётов.
Дальше работа с ними происходит ровно также, как и с (mouse_x / mouse_y).
Как изменить курсор правильно?
Вопрос, который возник в комментариях. Подумал, что кому-то ещё может пригодиться.
Для изменения курсора существует переменная cursor_sprite, назначение спрайта которой изменит спрайт курсора. Пример ниже.
cursor_sprite = sprCursor;
Также, если вы хотите скрыть "системный курсор", то для этого существует команда:
window_set_cursor(cr_none)
Со списком всех возможных курсоров можно ознакомиться по ссылке ниже:
https://manual.yoyogames.com/GameMaker_Language/GML_Referenc...
На этом предлагаю закончить, так как непосредственно о рисовании GUI выше рассказано всё.
Надеюсь, что я смог ответить на все вопросы и знания выше помогут вам с разработкой игр в дальнейшем.
Добра!