Как сделать переход в другую комнату в game maker

Обновлено: 04.07.2024

Объекты - это суть Game Maker. Об объектах можно думать, как о некоторой сущности, которая имеет свои характеристики и по-своему реагирует на события, после чего выполняет предписанные разработчиком игры действия. Главный герой в вашей игре будет объектом, все враги - тоже. Различные препятствия и ловушки в игре - также объекты. Объектами будут снаряды, предметы, бонусы. Всякие менеджеры контроля уровней, отображения интерфейса, даже кнопки главного меню могут быть объектами (а могут и не быть, уж как пожелаете). В общем объекты - это основа нашей игры и её динамическая составляющая.

Создать новый объект можно кликнув кнопку на панели инструментов "Create an Object", или кликнув правой кнопкой по папке Objects в панели ресурсов и выбрав пункт "Create Object". Откроется окошко, элементы которого мы сейчас рассмотрим.

Sprite: Здесь вы сможете указать стандартный спрайт для объекта. Если вы не укажите спрайт, вы не сможете увидеть объект в игре. Конечно, это не важно, если вы будете рисовать вместо стандартного спрайта спрайт с помощью функций рисования. А может, вам и не нужно, чтобы объект могли увидеть :Р

Visible: Снятие галочки делает объект невидимым, т.е., он прячет стандартный спрайт, и объект перестаёт реагировать на события рисования. Тем не менее, это не деактивирует объект, он по-прежнему реагирует на события столкновения и выполняет все свои действия.

Solid: Сделать объект твёрдым. Свойство твёрдости нужно для того, чтобы в некоторых случаях по-другому обрабатывались события столкновения. Твёрдыми, к примеру, можно сделать стены и платформы.

Depth: "Глубина" объекта на экране. Чем больше это число - тем ниже остальных объектов будет отображаться. Уменьшение этого числа выносит объект на передний план, т.е. ближе к зрителю. Свойство нужно, чтобы правильно позиционировать объекты относительно перспективы - ближние и дальние объекты. Также, всё, что нарисует объект, будет отображаться на той же глубине (или слое, если вам так проще понимать). Так что объекты, которые рисуют, к примеру, интерфейс, должны иметь большую отрицательную глубину. Я, к примеру, для таких объектов просто ставлю -99999 и забываю об этом. Объекты, которые имеют одинаковую глубину, будут отображаться в порядке создания - сверху последние созданные.

Persistent: Делает объект постоянным. Постоянные объекты не исчезают при переходе в другую комнату, они существуют постоянно, постоянно реагируют на события и выполняют действия. Так что, такие объекты нужно удалять вручную. Очень полезное свойство для всяких системных объектов, которые следят за вашей игрой и т.д.

Mask: Задаёт спрайт-маску объекту. Маска используется для детекта коллизий. По-умолчанию, за это отвечает стандартный спрайт, но если вы выбрали другой спрайт в качестве маски, именно он будет использоваться для коллизий, хотя стандартный спрайт будет отображаться по-прежнему. Очень часто нужно, чтобы объект реагировал на столкновения с другими объектами по спрайту совсем другой формы, чем его родной спрайт.

Show Information: Показывает подробную информацию по объекту в отдельном окне и удобочитаемом формате.

Поля Events и Actions: Это списки событий, на которые реагирует данный объект и действия, которые он при этом выполняет. Более подробно об этом читайте здесь.

Если мыслить гуманитарно и при этом представить, что объект - это биологический вид какого-то животного, то образец объекта - это каждый представитель этого вида. Такая маленькая пугливая копия великого и могучего. Именно образцы объектов участвуют в вашей игре. Но, если вы назовёте образец объектом, ошибки не будет (можете даже называть их экземплярами). Однако, иногда важно различать объект и его образцы. Каждый образец - точная копия своего объекта, хотя в процессе игры может измениться и совершенно отличаться от других таких же образцов объекта. Образцы объектов можно создавать и удалять во время игры и делать с ними то, что заблагорассудится. Итак, объект - это основа, образец - конкретный представитель в игре, к которому можно обращаться по номеру.

У каждого образца в игре есть свой уникальный числовой номер (говоря научно, идентификатор), которые начинаются со значений больше 100000. Именно по идентификатору можно обратиться к конкретному образцу в игре, ведь у вас таких образцов может быть очень много, а вам нужен именно вот этот - конкретный я назову его Билли. Так вот, если в комнате есть всего один Билли образец объекта, например, главного героя, вы можете обращаться к нему по имени объекта. Иначе, по имени объекта вы обратитесь лишь к самому первому из созданных образцов. Поэтому, в каждом из образцов есть свойство (встроенная переменная, самих свойств у объектов очень много) под названием id , которую нельзя изменить и которая содержит идентификатор - т.е. Билли уникальный номер этого образца.

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

Примечание: то, о чём я буду рассказывать дальше, касается лишь gml-кода, я понятия не имею, как конкретные образцы идентифицируются через гуи-иконки. Так что крайне приветствуется хоть какие-то познания в программировании.

Итак, нам нужно, чтобы один образец объекта мог получить или сменить значение какой-то переменной из другого образца этого или совсем другого объекта. Нам не важно какой переменной - ту, что вы огласили сами, например, текущее здоровье или количество патронов, или переменную-свойство.
Давайте из другого образца обратимся к образцу Билли и поменяем свойство x (эта переменная содержит координату объекта по оси Х, можно менять для перемещения объекта).
Если объект у нас в комнате один, всё просто - вспоминаем предыдущий пункт статьи и обращаемся к образцу по имени объекта.

Хм, вроде всё просто. Как видите, мы просто написали имя объекта, а через точку - его переменную и тут же изменили её. Это же работает и в обратную сторону:

Надеюсь, вы догадались, что мы передали в переменную а значение координаты х образца Билли? Вроде понятно.
Так, но вот что делать, если образцов в комнате появилось несколько? А вот тут и начинаются пляски с бубном. Есть разные варианты идентифицировать конкретный образец.
Например, вы можете в скобках написать его уникальный номер, если вы его знаете. Обычно, это применимо образцам, которые вы расставили в редакторе комнаты - там вы сможете увидеть номер образца на нижней панели, наведя на него курсор.

Это очень неудобный способ, не так ли?
Тогда допустим, вы создаёте объекты в комнате в процессе игры. Самый лучший вариант - записать только что созданный образец в переменную. Образцы создаются с помощью функции instance_create(x, y, obj). Функция возвращает идентификатор нового образца, т.е. его id .

Теперь в переменной neb у нас содержится только что созданный образец Билли. Вот теперь мы и поменяем ему x (Примечание: хотя, по сути, это бессмысленно. Ведь мы же создали образец уже по нужным нам координатам х:250, y:350. Но так тому и быть. Кстати, не воспринимайте буквально слова об образце в переменной. На самом деле, в переменной записан идентификатор образца. Нюансы движка. Пока не вникайте, я выразился так для простоты) :

В этом случае мы просто больше не сможем обратиться к Билли снова, поскольку у нас нигде не будет записан его идентификатор. Однако, иногда большего и не требуется.
Или вовсе наркомания так:

Ещё для идентификации образцов можно использовать конструкцию with. Есть также и другие способы идентификации, но для начала подойдут и эти.

Пора поговорить об особых объектах: self, other, noone, all. Они выполняют особую функцию и облегчают нам жизнь хоть в чём-то*

  • self - это сам же объект. Вы не поверите, как часто это может понадобиться. Ведь образцу может понадобиться иногда обращаться к самому себе!**
  • other - это объект, который столкнулся с нашим объектом (событие коллизии). Ещё, объектом other будет выступать объект вне конструкции with, тот, который её вызвал, для объектов внутри конструкции (и зачем вы это прочитали).
  • noone - ни один объект, или несуществующий объект с Тоже иногда может пригодиться.
  • all - все образцы в игре. Смотрим пример:

В общем, я думаю, для начала новичку вполне достаточно этой информации, понимание всех нюансов придёт со временем. Кое-что может показаться сложным, но не настолько, чтобы немного погодя в этом не разобраться самому. Главное - практика, опыт и понимание придут со временем.
Важно помнить, что объекты - это наше всё, именно благодаря им мы можем создать игру, описать ими геймплей и игровую логику.

Я покажу, как реализовать передвижение, коллизию, прыжки, гравитацию, ускоряющие платформы, платформы для прыжков, смерть от шипов и падения за карту, переход на следующий уровень и порталы.

Перед началом желательно иметь хоть какие-нибудь навыки работы с Game Maker Studio. Рекомендую ознакомиться с интерфейсом программы.

В событии Create объявим следующие переменные:

xDir - направление движения игрока по горизонтали. Переменная будет равна:
-1 — если игрок идет налево;
1 — если игрок идет направо;
0 — если игрок стоит на месте.

stepLength - длина шага игрока в пикселях. Пускай переменная будет равна 10.

dx - сдвиг по горизонтали. Каждое обновление комнаты (по умолчанию — 60 обновлений в секунду) игрок будет сдвигаться на dx пикселей. dx будет вычисляться перемножением xDir и stepLength.

Переменные можно объявить другим способом: в специальном разделе Variable Definitions.

В событии Step напишем следующее:

Переменная x относится к тем переменным, которые есть в каждом созданном вами объекте. Они определяются автоматически, без вашего участия и выделяются зеленым цветом в коде. Список всех таких переменных.

Первая строка вычисляет направление движения. Функция keyboard_check(key) принимает в качестве аргумента клавишу и возвращает true, если она нажата. Функция ord(string) принимает в качестве аргумента строку и преобразует ее в необходимый тип данных для аргумента функции keyboard_check(key). Таким образом, при удержании клавиши "A" переменная xDir становится равной -1, а при удержании клавиши "D" - 1.

Вторая строка вычисляет dx.

Третья строка увеличивает x на dx пикселей, то есть двигает игрока.

Создаем комнату и добавляем на слой Instances экземпляр объекта игрока.

Запускаем и убеждаемся, что все работает как надо.

Здесь никаких переменных и событий создавать не надо: код для взаимодействия с объектом напишем внутри oPlayer в событии Step. Перепишем его так, чтобы событие выглядело следующим образом:

xDir = -keyboard_check(ord("A")) + keyboard_check(ord("D")); dx = xDir * stepLength; if (!place_meeting(x + dx, y, oSolid)) //эта строчка новая x += dx;

place_meeting(x, y, obj) нужна для проверки пересечения прямоугольников коллизии двух объектов. Она принимает три аргумента:
x - позиция первого объекта по оси x;
y - позиция первого объекта по оси y;
obj - имя второго объекта или id его экземпляра.
Функция возвращает true, если объекты пересекаются и false - если нет. Важно то, что проверка осуществляется не в одной лишь точке (x; y), а сразу во всех точках прямоугольника вызывающего объекта. Для проверки коллизии в одной точке имеется функция position_meeting(x, y, obj), но она нам не понадобится. Используя place_meeting(x + dx, y, oSolid), мы проверяем пересечение игрока с твердым объектом, как если бы игрок был сдвинут на dx пикселей. И только убедившись, что пересечения нет, меняем координату игрока.

Теперь нужно создать объект oWall, установить ему родителя oSolid и привязать к нему какой-нибудь спрайт. В моем случае это черный квадрат 64x64. Позже в редакторе комнаты экземпляры этого объекта можно будет растянуть.

Создадим небольшую комнату и расставим там несколько oWall, чтобы проверить работоспособность.

Я хочу сделать так чтобы было соответствие между картами. То есть когда ты переходишь например в крайнем левом углу карты на другую локацию ты появляешься относительно этого мира в том же самом месте То есть например шёл ты по дороге перешел по дороге прошел пару метров от дороги на следующей локации Ты оказался тоже на пару метров от дороги. Извините за безграмотность говорю это в Google

Тестер
Проект месяца 1 место
Проект месяца 3 место
Оратор

Паладин
Ветеран
Программист Ruby
Учитель
Поддержка Фонда
2 место
Проект месяца 3 место
За 2 место на конкурсе маппинга
Оратор
Даритель Стимкея

Спасибо Весёлому Роджеру за полезную ссылку! Она пригодится для тех, кто хочет сделать двери в RPG Maker VX Ace и MV.

Хочу немного дополнить и описать, как сделать переход не по дверям RPG Maker XP (судя по значку этой темы, Oltal использует его).

1. События перехода

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

Проект-пример событий перехода для RPG Maker XP: TransferEvent.zip (~200 Кб)

В новых версиях RPG Maker (VX Ace и MV) есть готовые шаблоны для событий перехода, но в RPG Maker XP их надо делать вручную. К счастью, это легко.

Чтобы поставить событие, нужно перейти в режим редактирования событий (нажать на значок с кубиком на панели инструментов или F8) и щёлкнуть по той клетке, где будет переход.

Откроется окно редактирования событий. В нём в левой части нужно выбрать переход по касанию:

Если непонятно, гляньте в проекте-примере.

2. Переход по параллельному событию

Но если нужно, чтобы весь край карты действовал как переход на другую карту, то можно делать паралелльное событие. Это немного сложно, поэтому стоит сначала попробовать с событиями перехода.

Проект-пример переноса с параллельными событиями для RPG Maker XP: ParallelEventMovement.zip (~200 Кб)

В RPG Maker XP параллельное событие создаётся так:

  • Координата X — это расстояние от самой левой клетки до текущей. То есть у самой левой клетки координата X=0; у самой правой равна (ширина карты - 1).
  • Координата Y — это расстояние от самой верхней клетки до текущей. То есть у самой верхней клетки координата Y=0, у самой нижней — (высота карты - 1).

Координаты показываются через запятую: сначала X, потом Y:

(На этом примере правая клетка дупла расположена по координатам X=10, Y=9).

(Важно: нужно выбирать именно X и Y карты — расстояние в клетках от края карты. Есть ещё X и Y экрана — это расстояние в пикселях от края экрана до места героя на экране, это нам не нужно.)

Эти команды нужно записать в параллельное событие, чтобы они выполнялись постоянно в фоновом режиме:
@> ПЕРЕМЕННАЯ: [0001:Координата X] = Игрок X на карте
@> ПЕРЕМЕННАЯ: [0002:Координата Y] = Игрок Y на карте

  • переход налево: если координата X = 0,
  • переход направо: если координата X = ширина карты минус 1 (т.е. если карта шириной в 20 клеток, то переход направо, если X=19),
  • переход вверх: если координата Y = 0,
  • переход вниз: если координата Y = высота карты минус 1 (т.е. если карта высотой в 15 клеток, то переход направо, если X=14).

После добавления такой проверки код примет такой вид:

@> ПЕРЕМЕННАЯ: [0001:Координата X] = Игрок X на карте
@> ПЕРЕМЕННАЯ: [0002:Координата Y] = Игрок Y на карте
@> Ветвление условий: Переменная [0001:Координата X] == 19
@>
: КОНЕЦ
@>

Но тут есть загвоздка: если игрок перешёл на эту клетку с другой карты, то он тоже будет на этой клетке и переход тоже случиться. Лучше добавить проверку на направление игрока: пусть переход на правую карту случается только когда игрок смотрит вправо.

Код примет такой вид:
@> ПЕРЕМЕННАЯ: [0001:Координата X] = Игрок X на карте
@> ПЕРЕМЕННАЯ: [0002:Координата Y] = Игрок Y на карте
@> Ветвление условий: Переменная [0001:Координата X] == 19
@> Ветвление условий: Игрок + смотрит вправо
@>
: КОНЕЦ
@>
: КОНЕЦ
@>

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

Но! Чтобы ей воспользоваться, нам нужно установить переменные для новой карты.

  • переход налево: координата X устанавливается ширине левой карты - 1, координата Y не меняется,
  • переход направо: координата X устанавливается равной 0, координата Y не меняется,
  • переход вверх: координата X не меняется, координата Y устанавливается высоте верхней карты - 1,
  • переход вниз: координата X не меняется, координата Y устанавливается равной 0.

В итоге получится вот такое событие (для перехода вправо):

@> ПЕРЕМЕННАЯ: [0001:Координата X] = Игрок X на карте
@> ПЕРЕМЕННАЯ: [0002:Координата Y] = Игрок Y на карте
@> Ветвление условий: Переменная [0001:Координата X] == 19
@> Ветвление условий: Игрок + смотрит вправо
@> ПЕРЕМЕННАЯ: [0003:ID карты] == 2
@> ПЕРЕМЕННАЯ: [0002:Координата Y] == 0
@> Переместить игрока:из переменных [0003][0001][0002]
@>
: КОНЕЦ
@>
: КОНЕЦ
@>

В результате игрок будет переходить по любой клетке на краю карты.

Если это сложно — не волнуйтесь! Вы можете использовать первый способ и просто заставить всю правую часть карты событиями перехода вместо параллельного события. Это медленнее, но проще для понимания. Способ с параллельными событиями сложный, и если вы его не понимаете, это не страшно.

А если все-таки решите разбираться с параллельными событиями, посмотрите на проект-пример.

В Game Maker каждый объект может иметь набор событий, которые запускают выполнение определённых действий. Всё. Вся "логика" игры строится именно по этому принципу. Если происходит определённое событие - выполняются созданные для него действия. Просто, не так ли? Эти события могут быть как персональными, так и глобальными, но в GM они никак не разделяются на типы, оно и к лучшему. Вы можете создавать для разных объектов разные события и определять какие угодно действия. Именно таким образом и будет работать вся ваша игра.
События создаются и редактируются в окне объекта, в поле-списке "Events", с помощью трёх кнопок "Add event" (Создать событие), "Destroy" (Удалить событие), "Change" (Сменить событие с сохранением списка действий), или в контекстном меню поля с аналогичными командами. В контекстном меню добавляется дополнительная команда "Duplicate event", которое лишь копирует список действий, а событие вам всё равно придётся выбрать заново.

События и стандартные действия в Game Maker — Game Maker — DevTribe: инди-игры, разработка, сообщество

Итак, создаём событие, кликая по волшебной кнопочке. Открывается крохотное, в прямом смысле этого слова, окошко со всеми событиями GM. Некоторые события при нажатии на свою кнопку открывают контекстное окно, в котором вам предлагается уточнить событие, выбрать его определённый вид.

События и стандартные действия в Game Maker — Game Maker — DevTribe: инди-игры, разработка, сообщество

Все события располагаются в списке в определённом порядке, а именно - в порядке срабатывания. Т.е. первыми всегда срабатывают события создания образца, потом - уничтожения, потом - события нажатия кнопок клавиатуры и т.д. и т.д. Это очень важно помнить.

Описание событий или "Я не придумал ничего лучше"

Давайте по порядку, как на картинке, я опишу события и их виды.

  • Create - всё просто, это событие выполняется, когда создаётся экземпляр объекта. Обычно используется, чтобы задавать "начальные" характеристики объекта, всякие там переменные и т.д., но может иметь и более широкое применение. Например, объекты, которые вы расположили в комнате через редактор, тоже создаются, когда комната запускается. Можно использовать такие объекты для объявления глобальных переменных и прочего и прочего. Однако, для таких как я, были созданы такие события, как Game Start и Room start, о которых речь ниже.
  • Destroy - ещё проще, это событие выполняется, когда экземпляр объекта удаляют. Можно применить, например, чтобы создать кровавое пятно на месте врага.
  • Alarm - а вот это уже интересней. Это событие таймера. Каждый экземпляр объекта может заиметь до 12-ти таймеров, каждый их них будет подписан в списке событий как Alarm0, Alarm1, Alarm2 и т.д. С помощью определённого действия или кода, можно запустить нужный таймер и по его истечению, выполнятся нужные действия я иногда использовал алярмы чтобы персонажи моргали глазами :3 , диапазон применения - очень широк, иногда даже 12-ти таймеров не хватает.
  • Step - событие "шага", архиважное событие, находит применение практически всегда. Вам нужно перемещать объект за курсором? Вам нужно событие "шага". Нужно постоянно перемещать образцы по координатам? Вам нужно событие "шага". Нужно отследить монстров на наличие бафов? Вам нужно событие "шага". Это событие выполняется "постоянно", то есть, каждый игровой "шаг". Как его определить? В окне комнаты есть такое поле, как "Room speed" - это скорость комнаты, и по сути, скорость игры, т.е. FPS - количество кадров в секунду. Так что, если у вас скорость текущей комнаты 60 fps или шагов - событие "шага" будет срабатывать 60 раз в секунду. Вуаля. Рассмотрим виды этого события:
  • Step - самое распространённое событие, срабатывает как раз после событий создания и уничтожения, но перед всеми остальными. Очень удобно отлавливать этим событием кнопки клавиатуры или мышки.
  • Begin step - это событие шага срабатывает перед всеми остальными событиями, хотя в списке оно и идёт где-то посредине.
  • End step - это событие шага срабатывает после всех остальных событий, но перед событием рисования.
  • Collision - событие "столкновения". Срабатывает, когда спрайт или маска объекта пересекаются со спрайтом другого объекта. В контекстном меню это событие предлагает выбрать с каким объектом нужно чтобы текущий объект сталкивался. Потому этих событий может быть много - для каждого из предопределённых объектов. Самое распространённое применение - столкновение пули со стеной, конечно же.
  • Keyboard - событие нажатия на кнопку клавиатуры. Но не обычное. Это событие срабатывает каждый шаг, пока кнопка нажата. Предлагает на выбор множество различных кнопок, от алфавитных до функциональных и прочих Backspace'ов. Потому это событие может быть у объекта не одно - зависит от количества кнопок, нажатия на которые вам нужно отлавливать. Стоит отметить лишь событие Keyboard - No key и Keyboard - Any key. Первое срабатывает постоянно, каждый игровой шаг, пока не нажата ни одна кнопка. Второе - срабатывает постоянно, пока нажата любая кнопка на клавиатуре. Наркомания, не так ли? Эти два вида событий есть и у других событий клавиатуры, о которых речь ниже.
  • Mouse - это все события мышки. Давайте рассмотрим их виды:

События и стандартные действия в Game Maker — Game Maker — DevTribe: инди-игры, разработка, сообщество

  • Left/Right/Middle button - события мышки, которые срабатывают каждый шаг, пока курсор наведён на спрайт объекта и при этом зажата левая/правая кнопка мышки или колёсико. Да-да, колёсико мышки бывает кликабельное.
  • No button - аналогично предыдущим, только событие срабатывает постоянно, пока не нажата ни одна из кнопок мышки (не стоит забывать, что курсор всё ещё должен быть на спрайте, поскольку это персональные события).
  • Left/Right/Middle pressed/released - эти события отличаются от предыдущих тем, что срабатывают лишь один раз, когда кнопка мышки нажата (pressed)/отпущена (released), а курсор находится на спрайте объекта. Когда событие сработало один раз, оно не будет срабатывать, пока пользователь не нажмёт/отпустит нужную кнопку ещё раз.
  • Mouse enter/leave - событие срабатывает, когда пользователь наводит/уводит курсор со спрайта или маски объекта. Очень удобное событие чтобы делать, например, всплывающие описания для предметов.
  • Mouse wheel up/down - эти события срабатывают, когда пользователь прокручивает колёсико мышки вверх/вниз. Глобальное событие.
  • Global mouse - а вот это уже очень важные события, которые отлавливают события шага/нажатия/отпускания кнопок мышки на общем уровне, т.е. событие глобальное, и потому не нужно, чтобы курсор находится на спрайте объекта. Находят применение чаще всех остальных.
  • Joustick 1/2 - честно говоря, никогда ими не пользовался. Это события для буржуйских джойстиков - когда нажата нужная ось или кнопка.
  • Other - прочие события, которые не вошли в основные категории событий. Вот они:

События и стандартные действия в Game Maker — Game Maker — DevTribe: инди-игры, разработка, сообщество

  • Outside room - событие срабатывает, когда объект покидает границы текущей комнаты. Можно использовать, например, для удаления таких образцов.
  • Intersect boundary - событие срабатывает, когда спрайт объекта пересекает границу комнаты.
  • Outside/Boundary view X - аналогично предыдущим двум событиям, только для одного из семи доступных видов (проще - игровых камер).
  • Game start/end - из названия понятно, что эти два события срабатывают лишь по одному разу за игру - в её начале и в конце. Это глобальные события, обычно используются для инициализации игровых данных. Часто game end используется чтобы закрывать dll'ки и удалять прочие непотребства из памяти, даже не смотря на то, что GM большинство из таких операций делает автоматически.
  • Room start/end - аналогично предыдущим, только для игровых комнат. В GM комнаты - это, по сути, игровые уровни. Так вот, эти события срабатывают, когда текущая комната запускается/заканчивается. Стоит помнить, что событие может срабатывать многократно, поскольку игрок может выходить/возвращаться в комнату. Тем более, нам не важно, какая это комната, поскольку мы сможем написать нужное условие на проверку имени/номера текущей комнаты, перед выполнением нужных действий.
  • No more leaves/health - это события для встроенных в GM систем здоровья и жизней, события срабатывают, когда они заканчиваются (равны нулю). Не понятно, кто ими пользуется, ведь намного проще объявить две-три переменных и сделать свою системку здоровья.
  • Animation end - это событие также для встроенной в GM системы анимаций. По сути - срабатывает когда все кадры у спрайта объекта проигрываются до последнего. Иногда полезно, но снова же, проще написать свою гибкую систему анимаций.
  • End of path - событие срабатывает, когда объект подходит к концу пути. Тоже иногда полезно.
  • Close button - событие срабатывает, когда нажимают кнопку закрытия игры - т.е. на крестик окна игры. Это же событие должно срабатывать и для кнопки Esc, если в настройках игры установлена такая возможность.
  • User defined X - это пользовательские события, их доступно до 16-ти штук. Срабатывания этих событий можно выполнить лишь через код, с помощью специальной функции. Редко, но находят применение.
  • Draw - вот мы и подобрались к самому интересному событию. Это событие "рисования". В своё время никак не мог понять, что оно делает и как им пользоваться, но когда разобрался, приятно удивился. Итак, событие рисования. Когда вы добавляете его объекту, он перестаёт отображать свой стандартный спрайт, не смотря на то, что события столкновения срабатывают как прежде, по сути делает объект невидимым. Это событие срабатывает каждый шаг и предназначено для динамической перерисовки. Вы делаете свою систему анимаций и нужно нарисовать спрайт персонажа? Вам нужно это событие. Вам нужно отобразить текст на экране или создать свой интерфейс? Вам нужно это событие. Вы хотите, чтобы у ваших юнитов были полоски здоровья, а при наведении на них курсора отображались всплывающие подсказки? Для всего этого существует событие рисования. Только сюда можно добавлять действия и функции рисования (обычно начинающиеся с draw_, например, draw_sprite() или draw_text() и т.д.), чтобы они работали. Кстати, поскольку это событие также срабатывает каждый шаг, после всех остальных событий (перерисовка объекта происходит в самом конце каждого шага, уже после того, как его изменили и переместили в новую позицию), поэтому его можно использовать вместо события Step, хотя это и не рекомендуется. В общем, мощнейший инструмент, нужен всегда и везде.
  • Key pressed и следующее за ним Key released - события нажатия/отпускания кнопок клавиатуры. В отличии от указанных выше событий Keyboard, срабатывают не каждый шаг, а лишь один раз, после чего пользователь должен отпустить/нажать кнопку снова. Используются чаще всего, например, для управления персонажем/машинкой/т.д.
  • Trigger - это новый вид событий, который появился в Game Maker 8. При добавлении этого события открывается окошко редактирования триггеров - это новый ресурс GM, хоть их и нельзя добавлять в структуру игры напрямую. В этом окошке вам предлагается в виде кода прописать условие, которое будет проверяться каждый шаг, и событие будет выполняться тогда, когда условие истинно, т.е., по сути, триггеры - это одна из модификаций события Step. Вы можете написать туда не только условие, но и вообще какой угодно код, который будет выполняться каждый шаг. Уже не говоря, что к этому событию можно и нужно добавлять действия в списке действий. Не очень понятно, зачем они нужны, ведь тех же самых результатов можно добиться, используя событие Step. По-видимому, они позиционировались как уникальные пользовательские события. Но раз их добавили - значит, иногда они всё-таки очень нужны.

События и стандартные действия в Game Maker — Game Maker — DevTribe: инди-игры, разработка, сообщество

Итого, вот и все события, которые есть в Game Maker, но их хватит на все случаи жизни. Поскольку каждому объекту можно задать свой набор событий, это заметно упрощает построение логики игры, позволяет реализовать тот или иной момент разными способами. Такая гибкость наравне с объектами - фишка GM, и одновременно - его наказание, поскольку многие моменты приходится реализовать вручную, которые уже встроены по-умолчанию в другие конструкторы. Также, поскольку каждому событию можно задать список действий, нужно рассмотреть стандартные действия, т.е., привычные каждому модмейкеру на варкрафте гуи-иконки, так называемые библиотеки стандартных действий.

Стандартные действия или "Почему я всё ещё это читаю?"

Итак, вы добавили объекту событие. Теперь, в соседнем поле "Actions" вы можете добавлять действия, которые просто перетягиваете из панельки с закладками справа в список. Все действия выполняются в порядке расположения в списке - сверху вниз. Их можно перетягивать вверх-вниз, копипастить и так далее.

События и стандартные действия в Game Maker — Game Maker — DevTribe: инди-игры, разработка, сообщество

При перетягивании большинства действий открывается окно настроек этого действия - там вы задаёте все нужные данные. Редактирование уже добавленного действия выполняется последствием двойного клика на иконку в списке.
По-моему, проще некуда. Хотя, на самом деле, продвинутому пользователю нужно всего одно действие - блок кода "Code" на закладке "Control", нужно рассмотреть все стандартные действия, хоть это и не очень удобный и громоздкий способ задавать логику игры.

Объекты - это суть Game Maker. Об объектах можно думать, как о некоторой сущности, которая имеет свои характеристики и по-своему реагирует на события, после чего выполняет предписанные разработчиком игры действия. Главный герой в вашей игре будет объектом, все враги - тоже. Различные препятствия и ловушки в игре - также объекты. Объектами будут снаряды, предметы, бонусы. Всякие менеджеры контроля уровней, отображения интерфейса, даже кнопки главного меню могут быть объектами (а могут и не быть, уж как пожелаете). В общем объекты - это основа нашей игры и её динамическая составляющая.

Создать новый объект можно кликнув кнопку на панели инструментов "Create an Object", или кликнув правой кнопкой по папке Objects в панели ресурсов и выбрав пункт "Create Object". Откроется окошко, элементы которого мы сейчас рассмотрим.

Sprite: Здесь вы сможете указать стандартный спрайт для объекта. Если вы не укажите спрайт, вы не сможете увидеть объект в игре. Конечно, это не важно, если вы будете рисовать вместо стандартного спрайта спрайт с помощью функций рисования. А может, вам и не нужно, чтобы объект могли увидеть :Р

Visible: Снятие галочки делает объект невидимым, т.е., он прячет стандартный спрайт, и объект перестаёт реагировать на события рисования. Тем не менее, это не деактивирует объект, он по-прежнему реагирует на события столкновения и выполняет все свои действия.

Solid: Сделать объект твёрдым. Свойство твёрдости нужно для того, чтобы в некоторых случаях по-другому обрабатывались события столкновения. Твёрдыми, к примеру, можно сделать стены и платформы.

Depth: "Глубина" объекта на экране. Чем больше это число - тем ниже остальных объектов будет отображаться. Уменьшение этого числа выносит объект на передний план, т.е. ближе к зрителю. Свойство нужно, чтобы правильно позиционировать объекты относительно перспективы - ближние и дальние объекты. Также, всё, что нарисует объект, будет отображаться на той же глубине (или слое, если вам так проще понимать). Так что объекты, которые рисуют, к примеру, интерфейс, должны иметь большую отрицательную глубину. Я, к примеру, для таких объектов просто ставлю -99999 и забываю об этом. Объекты, которые имеют одинаковую глубину, будут отображаться в порядке создания - сверху последние созданные.

Persistent: Делает объект постоянным. Постоянные объекты не исчезают при переходе в другую комнату, они существуют постоянно, постоянно реагируют на события и выполняют действия. Так что, такие объекты нужно удалять вручную. Очень полезное свойство для всяких системных объектов, которые следят за вашей игрой и т.д.

Mask: Задаёт спрайт-маску объекту. Маска используется для детекта коллизий. По-умолчанию, за это отвечает стандартный спрайт, но если вы выбрали другой спрайт в качестве маски, именно он будет использоваться для коллизий, хотя стандартный спрайт будет отображаться по-прежнему. Очень часто нужно, чтобы объект реагировал на столкновения с другими объектами по спрайту совсем другой формы, чем его родной спрайт.

Show Information: Показывает подробную информацию по объекту в отдельном окне и удобочитаемом формате.

Поля Events и Actions: Это списки событий, на которые реагирует данный объект и действия, которые он при этом выполняет. Более подробно об этом читайте здесь.

Если мыслить гуманитарно и при этом представить, что объект - это биологический вид какого-то животного, то образец объекта - это каждый представитель этого вида. Такая маленькая пугливая копия великого и могучего. Именно образцы объектов участвуют в вашей игре. Но, если вы назовёте образец объектом, ошибки не будет (можете даже называть их экземплярами). Однако, иногда важно различать объект и его образцы. Каждый образец - точная копия своего объекта, хотя в процессе игры может измениться и совершенно отличаться от других таких же образцов объекта. Образцы объектов можно создавать и удалять во время игры и делать с ними то, что заблагорассудится. Итак, объект - это основа, образец - конкретный представитель в игре, к которому можно обращаться по номеру.

У каждого образца в игре есть свой уникальный числовой номер (говоря научно, идентификатор), которые начинаются со значений больше 100000. Именно по идентификатору можно обратиться к конкретному образцу в игре, ведь у вас таких образцов может быть очень много, а вам нужен именно вот этот - конкретный я назову его Билли. Так вот, если в комнате есть всего один Билли образец объекта, например, главного героя, вы можете обращаться к нему по имени объекта. Иначе, по имени объекта вы обратитесь лишь к самому первому из созданных образцов. Поэтому, в каждом из образцов есть свойство (встроенная переменная, самих свойств у объектов очень много) под названием id , которую нельзя изменить и которая содержит идентификатор - т.е. Билли уникальный номер этого образца.

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

Примечание: то, о чём я буду рассказывать дальше, касается лишь gml-кода, я понятия не имею, как конкретные образцы идентифицируются через гуи-иконки. Так что крайне приветствуется хоть какие-то познания в программировании.

Итак, нам нужно, чтобы один образец объекта мог получить или сменить значение какой-то переменной из другого образца этого или совсем другого объекта. Нам не важно какой переменной - ту, что вы огласили сами, например, текущее здоровье или количество патронов, или переменную-свойство.
Давайте из другого образца обратимся к образцу Билли и поменяем свойство x (эта переменная содержит координату объекта по оси Х, можно менять для перемещения объекта).
Если объект у нас в комнате один, всё просто - вспоминаем предыдущий пункт статьи и обращаемся к образцу по имени объекта.

Хм, вроде всё просто. Как видите, мы просто написали имя объекта, а через точку - его переменную и тут же изменили её. Это же работает и в обратную сторону:

Надеюсь, вы догадались, что мы передали в переменную а значение координаты х образца Билли? Вроде понятно.
Так, но вот что делать, если образцов в комнате появилось несколько? А вот тут и начинаются пляски с бубном. Есть разные варианты идентифицировать конкретный образец.
Например, вы можете в скобках написать его уникальный номер, если вы его знаете. Обычно, это применимо образцам, которые вы расставили в редакторе комнаты - там вы сможете увидеть номер образца на нижней панели, наведя на него курсор.

Это очень неудобный способ, не так ли?
Тогда допустим, вы создаёте объекты в комнате в процессе игры. Самый лучший вариант - записать только что созданный образец в переменную. Образцы создаются с помощью функции instance_create(x, y, obj). Функция возвращает идентификатор нового образца, т.е. его id .

Теперь в переменной neb у нас содержится только что созданный образец Билли. Вот теперь мы и поменяем ему x (Примечание: хотя, по сути, это бессмысленно. Ведь мы же создали образец уже по нужным нам координатам х:250, y:350. Но так тому и быть. Кстати, не воспринимайте буквально слова об образце в переменной. На самом деле, в переменной записан идентификатор образца. Нюансы движка. Пока не вникайте, я выразился так для простоты) :

В этом случае мы просто больше не сможем обратиться к Билли снова, поскольку у нас нигде не будет записан его идентификатор. Однако, иногда большего и не требуется.
Или вовсе наркомания так:

Ещё для идентификации образцов можно использовать конструкцию with. Есть также и другие способы идентификации, но для начала подойдут и эти.

Пора поговорить об особых объектах: self, other, noone, all. Они выполняют особую функцию и облегчают нам жизнь хоть в чём-то*

  • self - это сам же объект. Вы не поверите, как часто это может понадобиться. Ведь образцу может понадобиться иногда обращаться к самому себе!**
  • other - это объект, который столкнулся с нашим объектом (событие коллизии). Ещё, объектом other будет выступать объект вне конструкции with, тот, который её вызвал, для объектов внутри конструкции (и зачем вы это прочитали).
  • noone - ни один объект, или несуществующий объект с Тоже иногда может пригодиться.
  • all - все образцы в игре. Смотрим пример:

В общем, я думаю, для начала новичку вполне достаточно этой информации, понимание всех нюансов придёт со временем. Кое-что может показаться сложным, но не настолько, чтобы немного погодя в этом не разобраться самому. Главное - практика, опыт и понимание придут со временем.
Важно помнить, что объекты - это наше всё, именно благодаря им мы можем создать игру, описать ими геймплей и игровую логику.

Читайте также: