Как сделать стены в game maker studio 2

Обновлено: 14.05.2024

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

ПРИМЕЧАНИЕ В предыдущих версиях GameMaker функции столкновения использовали целочисленные значения, однако теперь они используют значения с плавающей точкой, что означает, что функции столкновения больше не будут округлять нецелые аргументы. Для получения дополнительной информации читайте раздел Режим совместимости при столкновениях.

Простая проверка столкновений

В следующих функциях рассматриваются различные способы, с помощью которых можно заставить экземпляр проверять столкновения с другим экземпляром:

Расширенная проверка столкновений

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

  • obj: Здесь мы указываем объект, столкновение с которым должна проверить функция. Это может быть идентификатор экземпляра, тип объекта или специальное ключевое слово GM all. Также стоит отметить, что если выбранный тип объекта является родителем других объектов, то все дочерние объекты этого объекта также будут включены в эту проверку.
  • prec: Это значение может быть либо true , либо false и относится к точности проверки столкновений. Если установлено значение true , то будут вычисляться точные столкновения (но только если проверяемый объект имеет в свойствах маски отметку "точно" для обнаружения столкновений), что является немного более сложной задачей для процессора и поэтому должно использоваться с осторожностью. Если false , то столкновения будут рассчитываться на основе граничной области проверяемого объекта.
  • notme: Вам может понадобиться проверить столкновения с объектом, который имеет тот же индекс, что и объект, выполняющий код, поэтому, чтобы код не нашел столкновения с самим собой, можно установить значение true . Если вы специально ищете экземпляр объекта, выполняющего код, или это не важно, можно оставить значение false .

Основные функции возвращают либо ID экземпляра, с которым произошло столкновение, либо специальное ключевое слово noone , если столкновения нет, а функции списка возвращают количество экземпляров, с которыми произошло столкновение, и заполняют их ID предварительно созданный список DS. Обратите внимание, что если существует несколько столкновений с областями, определенными этими функциями, и экземплярами данного объекта, возвращается только один ID экземпляра, и это может быть любой из экземпляров в столкновении.

Существуют следующие функции, которые работают с расширенными столкновениями.

Проверка столкновений без маски

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

Физические коллизии

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

Для начала нам предварительно нужно найти в папке Game Maker'а Exaples и в нём treasure.gmk. С его помощью будем изучать комнаты. Скачали? Тогда откройте этот файл и поиграйте немного, нажав на кнопку
Запустить игру. Если вы немного поиграли, приступим к изучению. Нажмите два раза на папку Rooms и два раза на room0.

Наведите курсором на иконки сверху и изучите их. Некоторые из них не переведены, поэтому смотрите, что они обозначают:
1) Очистить комнату 2) Двигать объекты/тайлы на X и Y пикселей 3) Отразить горизонтально все объекты/тайлы 4) Отразить вертикально все объекты/тайлы 5) "Заморозить" объекты/тайлы в комнате (запретить удаление) 6) "Разморозить" объекты/тайлы в комнате (разрешить удаление).

Откройте вкладку Установки. В ячейке Имя можно написать имя комнаты. В ячейке Заголовок комнаты можно написать текст, который будет отображаться в названии окна. Ширина и высота обозначают ширину и высоту комнаты. Сделайте ширину 640, а высоту 480. Когда вы играли в игру, то наверно заметили, что с каждым уровнем скорость игры увеличивается. Это делается с помощью значения Скорость. Скорость - это количество действий, которые делаются в секунду. Если поставить галочку Постоянный, в игре, если покинуть эту комнату и снова туда вернуться, содержимое комнаты будет оставаться таким же, каким вы его видели в последний раз. Нажав на кнопку Создать кодоткроется окно, в котором можно написать GML скрипт, который будет выполняться при создании комнаты.

Откройте вкладку Виды. Поставьте галочку Использовать виды. Вы включили использование видов. Всего можно использовать 7 видов. Поставьте галочку Включить вид в комнате. X и Y под надписью "Вид в комнате" это координаты вида в комнате, а W и H высота и ширина вида. Сделайте X 122, Y 192, W 250, а H 200. X и Y под надписью Порт на экране это координаты окна, а W и H высота и ширина окна. Для того чтобы вид следовал за объектом нужно нажать на ячейку под Следовать за объектом и выбрать там нужный объект. Выберите объект explorer. X гр и Yгр это граница вида, при "пересечении" которой вид начинает двигаться за объектом. Xск и Yск это скорости движения вида за объектом. Сделайте Xгр 125, Yгр 100, Xск 3,Yск 3.

Откройте вкладку Объекты. Чтобы выбрать объект который необходимо разместить в комнате нужно нажать на прямоугольную область выше надписи "Объект для доб.лев. кнопкой" и выбрать в появившемся списке нужный объект. Чтобы разместить объект в комнате нужно нажать левой кнопкой мыши на нужном месте. Добавьте объекты на пустое место в комнате. Чтобы объекты при совпадении координатами не удалялись нужно убрать галочку Удалить при обновлении. Для удаления объекта нужно нажать на него правой кнопкой мыши.

Откройте вкладку Тайлы. Тайл - это изображение, разделенное на кусочки. Чтобы выбрать тайл нужно нажать на прямоугольную область над галочкой "Удаление при обно." И выбрать там нужный тайл. Выберите background1. Тайл background1 разбит на четыре картинки. Выберите одну из них и разместите в комнате. Текущий слой - это слой, на котором размещены тайлы. Если тайлы размещены на слое 1000000 и мы, находясь на слое 1000001, попытаемся удалить талйы, то тайлы на слое 1000000 не удалятся. Чтобы добавить слой нужно нажать на кнопку Добавить. Чтобы удалить слой нужно нажать на кнопку Удалить. Чтобы изменить слой нужно нажать на кнопку Изменить.

Откройте вкладку Фоны. Поставив галочку Рисовать цвет фона цвет фона будет серым если не выбрано фоновое изображение. Цвет можно поменять, нажав на серый прямоугольник рядом с надписью "Цвет". Если убрать галочку Видим при старте фон не будет виден. Если поставить галочку на Рисунок на передний план, то фон будет на переднем плане. Чтобы выбрать фон нужно нажать на прямоугольную ячейку под галочкой "Рисунок на передний план". Гор.тайл и Вер.тайл обозначают, будет ли повторяться фон. X и Y это смещение фона на X и Y пикселей. Нажав на галочку Растягивание, фон растянется по всей комнате. Гориз.ск-ть и Верт.скорость это скорость движения фона.

Теперь создайте новую комнату и расставьте там объекты, сделайте фон, и разместите тайлы. Чтобы добавить комнату нужно нажать правой кнопкой мыши на папку Rooms и выбрать там Create Room.

И снова рад приветствовать всех вас на своем канале! В прошлых двух уроках мы с вами создали уровень с кирпичами, биту и мяч. Научили биту двигаться влево и вправо, сделали так, чтобы бита упиралась в стены.

А сегодня давайте уже наконец поработаем с мячом. Научим его летать, отскакивать от стен с битой и разбвать кирпичи.

Запускаем мяч

С прошлых уроков мы в мяч добавили всего одну строчку кода в событии шага:

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

Давайте добавим событие создания (Create) в объекте мяча и объявим в нем переменную:

Это булева переменная. Что это значит? Булева переменная - это та, что может иметь только два значения: true (истина) или false (ложь). Их можно заменить соответственно: 1 (истина) или 0 (ложь).

Я назвал переменную fixed, что значит "зафиксирован", и присвоил ей значение true (истина). Т.е. логически это можно понять как то, что при создании мяча, он зафиксирован. Теперь давайте подправим код в событи шага мяча:

Т.е. мы добавили проверку условия - если мяч зафиксирован, то его координата будет всегда равняться координате самой биты. Если вы запустите сейчас игру, то увидите, что ничего не изменилось. Но эта переменная нам пригодится далее, думаю вы уже сами понимаете для чего. Когда мы запустим мяч, то просто сменим данную переенную на false и тогда код в скобках <> выполянться не будет и соответственно мяч не будет следовать за битой.

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

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

Для этого достаточно нам добавить всего одно действие. А именно, назначить стену родителем для данного блока. Как это сделать и для чего?

Заходим в объект блока. Нажимаем на кнопку "Parent" (что переводится как "родитель").

Далее, в открывшемся окне жмем на три точки.

А там уже выбираем объект стены (Wall).

Щелкаем на него и все. Теперь для блока родителем назначен блок стены.

Что это значит? Вообще это достаточно обширная тема для изучения. Но для нас это значит, что мячу теперь не принципиально сталкивается ли он с объектом стены или с объектом блока, он все равно будет отскакивать. Так как для нашего мяча блок - это теперь тоже самое что и стена. Если в коде мяч каким-то образом взаимодействует со стеной, то и с блоком код повторится. Это конечно все очень утрировано. Но запустите игру на данном этапе и потестируйте.

Мяч теперь отскакивает как от стен, так и от блоков.

По этому добавьте еще несколько случаев проверки в коде. Необходимо сделать это перед тем, как приступать к написанию следующего кода, чтобы не запутаться!

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

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

Вот самый первый наш случай. Когда мяч летит влево и вверх. Тут есть три варианта: когда мяч сталкивается со стеной (а теперь и с блоком) сверху, слева и одновременно сверху и слева.

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

Здесь мы проверяем, если мяч летит влево вверх И над ним на spd пикселей выше есть объект стены, то мяч меняет направление на влево вниз (dir=2). Т.е. логично, что сюда нужно вклинеть кусок кода, где блок бы уничтожался.

Давайте эту первую строчку немного доработаем:

Так что же тут у нас. Т.е. условие не изменилось Все так же проверяем что направление у мяча dir=0 и есть объект стены выше, и если да, то так же меняем направление на dir=2.

Тут без изменений. А вот ниже добавлены еще три строчки.

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

Так вот, смотрим, в том же месте, где стоит стена(сверху) есть ли объект блока? Если да, то мы переменной b присваиваем id этого блока. А далее с объектом b производим уничтожение с помощью функции with .

И вот тут у нас появилось очень много нового. Для начала, давайте постараемся понять, что такое id объекта. Дело в том, что каждый объект, который мы ставим в уровень в редакторе комнат или создаем кодом, имеет свой уникальный номер. Через этот номер можно обратиться именно к этому образцу объекта.

Помните, мы обращались из объекта Биты к объекту мяча, когда нажимали клавишу пробел с помощью точки:

Т.е. в объекте Ball переменная fixed должна была сменться на false. В нашем случае все работает отлично, так как объект Ball один на уровне. А если бы у нас было несколько мячей? Данный код бы сменил переменную fixed у каждого мяча на false. Но что если бы мы захотели поменять данную переменную только у одного конкретного мяча на уровне? Т.е. у одного образца объекта. Вот тут как раз необходимо было бы обратиться по уникальному номеру - этому самому id .

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

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

Если кто-то уже писал об этом, пожалуйста, укажите, спасибо



Не зная дополнительных деталей о том, как устроен ваш проект / объекты, я собираюсь предложить только общие решения типа идеи.

1) При столкновении с объектом стены вы можете попытаться найти край объекта стены, используя размер спрайта, и добавить его в качестве точки для перемещения. (при условии, что стены не облицованы плиткой, а там есть еще одна стена)

2) Вы можете сделать резервную копию движения игрока, и следующий объект будет следовать по этому пути. Предполагая, что путь, по которому прошел игрок, все еще свободен и может быть пройден, любой путь, по которому прошел игрок, должен быть действителен и для следующего объекта.

3) Не уверен, что это соответствует механике вашей игры, но в некоторых играх (например, в diablo 3), если ваш спутник / домашние животные слишком далеко отстают от игрока, они просто автоматически телепортируются рядом с местоположением игрока.

Мне нравится твоя вторая идея. Однако я понятия не имею, как это реализовать. Это потому, что я не могу найти способ заставить объект игрока сохранять путь для врага: /

Для документации, связанной с путями, docs.yoyogames.com/source/dadiospice/002_reference/paths/… вы можете использовать path_add to, чтобы создать новый путь, path_add_point (), чтобы добавить новые точки к пути, и path_assign, чтобы скопировать резервный путь игрока в при необходимости новый путь для последователя. В качестве альтернативы я подумал, что другим подходом может быть добавление невидимого пути для поиска «узловых» объектов в этих проблемных областях, и если следующий объект застревает, они могут вместо этого выбрать путь к этим объектам, а затем следовать по пути, хранящемуся в этих «узлах». "идти по чистому пути?

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