Найти тему

Физика в Game Maker Studio (соединения)

Оглавление

Доброго времени суток, дорогие читатели! Сегодня я хотел бы немного рассказать о соединениях (Joints) в Box2D на движке Game Maker Studio. Они используются для соединения особым способом одного или нескольких физических тел между собой. С помощью джоинтов можно, например, создать веревку, прикрепить колеса к машине, сделать мост или дверь. Короче очень много интересных вещей.

В прошлых уроках я описал основы физики в Game Maker Studio. Вы научились создавать простейшие тела и задавать им некоторые свойства.

В этом же уроке я подробно опишу всего лишь один тип соединения, а на примере него уже любой сможет разобраться в остальных типах Joints, просто заглянув в справку. Зная основу, разобраться будет уже совсем не сложно.

Соединение, о котором я сегодня расскажу, joint revolute или как я его называю "шарнирное соединение". Итак, приступим!


Краткая теория

Сначала давайте попробуем представить, что это за тип соединения. Самое простое для понимания определение - это гвоздь или вал. Посмотрите на схему.

Схема шарнирного соединения
Схема шарнирного соединения

Тут у нас два физических объекта четырехугольника. Видите красную точку? Это и есть наше соединение. Т.е. синий объект как бы прибит к черному и может вращаться вокруг этой оси. Фантазия не работает? Давайте обратимся к более практичному примеру.

Схема соединения колес с машиной (спрайты взяты из сети)
Схема соединения колес с машиной (спрайты взяты из сети)

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

Машина в разборе
Машина в разборе

Или вот цепь. Одно звено скопировано несколько раз и каждые соседние звенья соединены как бы гвоздями в местах, отмеченных красными точками. Звенья могут вращаться вокруг этих осей.

Схема соединения звеньев цепи (спрайты взяты из сети)
Схема соединения звеньев цепи (спрайты взяты из сети)

Так думаю понятнее. Теперь перейдем к практике.

Практика

Сначала обратимся к справке. Функция, создающая данное соединение, выглядит так:


physics_joint_revolute_create (inst1, inst2, w_anchor_x, w_anchor_y, ang_min_limt, ang_max_limit, ang_limit, max_motor_torque, motor_speed, motor, col)

Вкратце опишу каждый параметр этой функции.

1) inst1 и inst2 - грубо говоря это первый и второй объект, которые будут соединены между собой. Если обратиться к примерам выше, то это черный и синий прямоугольники, или корпус машины и колесо или соседние звенья цепи. Но вместо inst1 мы указываем не сам объект (не его имя), а его идентификатор id. Для совсем уж не опытных скажу, что каждый объект, помещенный в комнату, содержит свой уникальный номер или идентификатор. Как его узнать, напишу чуть позже.
2) w_anchor_x и w_anchor_y - это X и Y координата той самой (красной на схемах) точки соединения.
3) ang_min_limt и ang_max_limit - это ограничения. Минимальный и максимальный угол на который может поворачиваться "прибитое" тело.
4) ang_limit - это значение может быть либо 0 (false) либо 1 (true), т.е. либо истина, либо ложь. Если оно равно 1, то ограничения угла, указанные выше, будут работать. Если же 0, то они просто будут игнорироваться и соединенное тело будет вращаться без ограничений на все 360 гр. Это пригодиться нам позже для колес.
5) Следующие три параметра связаны с вращением или так называемым "мотором". Если его не включать, то прикрепленное тело будет пассивно, т.е. просто болтаться и вращаться под действием других внешних сил. Если же его включить, то прикрепленное тело начнет принудительно вращаться. Это можно опять же использовать для колес. Так вот эти параметры соответственно отвечают за максимальную силу вращения (max_motor_torque), скорость вращения (motor_speed) и за наличие этого мотора (motor): 1 (true) или 0 (false), т.е. включен мотор или выключен. В примере с машиной его можно включить. В примере с цепью его следует отключить, иначе все звенья буду вращаться как безумные!
6) Последний параметр col - тоже либо 0 (false) либо 1 (true). Он означает могут ли два соединенных тела сталкиваться между собой или нет. Если 1, то они смогут сталкиваться (но только если мы дополнительно пропишем это в событии столкновения), если 0 (false), то они не будут сталкиваться независимо ни от чего.


Это была очень скучная часть, но многие параметры встречаются в других соединениях. Так что знать все же нужно. И не бойтесь, что можете запутаться в таком большом кол-ве параметров. Сейчас вы поймете на сколько все просто.

Создаем машину

Итак, машина. Создаем и рисуем два спрайта: колесо и сам корпус машины. Создаем 2 объекта: obj_car_body и obj_car_wheel. Пользуясь полученными знаниями из первых уроков, присваиваем им физические свойства и назначаем маски столкновения: для колеса - круг, для корпуса машины - прямоугольник, соответственно. Так же создадим объект стены (в первых уроках я так же описывал это подробно).

Объект машины
Объект машины
Объект колеса
Объект колеса

Отдельные части готовы. Теперь пора использовать соединение. Создаем новый объект obj_car к примеру. Ему не назначаем никакой спрайт, и не включаем галочку с физикой. А просто в событии создания Create прописываем такой код:

p1=instance_create_depth(x,y,10,obj_car_body)
p2=instance_create_depth(x-62,y+30,0,obj_car_wheel)
p3=instance_create_depth(x+62,y+30,0,obj_car_wheel)

physics_joint_revolute_create(p1,p2,x-62,y+30,0,0,0,0,0,0,0)
physics_joint_revolute_create(p1,p3,x+62,y+30,0,0,0,0,0,0,0)

Я думаю он понятен, но все же разберем поподробнее. Первые три строчки: мы создаем объект корпуса машины и два объекта колеса (обратите внимание на координаты колес, одно ниже и левее, второе ниже и правее). Координаты колес выставляете исходя из ваших рисунков (не забудьте в спрайтах колеса и корпуса машины установить якорь в Middle Centre). И записываем id (идентификаторы) объектов в переменные p1,p2 и p3. Я выше писал, что при создании соединения параметры inst1 и inst2 должны быть идентификаторами объектов.
Далее создаем соединение корпуса с первым колесом и соединение корпуса со вторым колесом. Обратите внимание, что из параметров указаны только id первого и второго объекта и координаты соединения (которые совпадают с координатами центров соответствующих колес). Все остальные параметры выставлены на 0. Они нам не нужны. Нам не нужно ни ограничение углов (колеса вращаются вокруг своей оси), ни мотор и т.д.

В объекте колеса прописываем событие столкновения со стеной.
Далее просто ставим объект Car (именно Car, а не Car_body или Car_wheel) в комнату, в которой предварительно расставляем стены и получилось вот что:

Расставленные объекты стены в редакторе уровня и сама машина
Расставленные объекты стены в редакторе уровня и сама машина

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

Запустив, вы увидите как машинка скатится с горки и вернется обратно.

Создаем цепь

Давайте теперь создадим цепь. Подробно останавливаться не буду и напишу сразу код. А вы, исходя из полученных за эти уроки знаний, думаю уже сами сможете его понять и разобрать. Итак, создаем два спрайта: один из них звено цепи, второй просто круг. Зачем он нужен сейчас поймете. Далее создаем два объекта. Один obj_chain_pin, второй obj_chain_part. В obj_chain_part выставляем спрайт звена цепи, все физические свойства по аналогии и прямоугольную маску столкновений. В obj_chain_pin выставляем спрайт круга и в свойствах параметр Density (плотности) ставим на 0, как мы это делали со стеной в прошлых уроках. Объясняю зачем это нужно и зачем нам вообще этот объект. Когда мы создадим цепь, то она всегда будет падать вниз под действием тяжести звеньев. Т.е. нам нужно эту цепь куда-то "привязать". Для этого и создаем "неподвижный объект" obj_chain_pin к которому мы ее привяжем. Вот звено у нас готово, булавка (как я ее называю) готова. Теперь создаем саму цепь. Создаем объект obj_chain (аналогичный объекту obj_car). Ему мы не задаем никакие физические свойства, никаких спрайтов и масок столкновений. А просто в событии Create прописываем код:

chain=instance_create_depth(x,y,6,obj_chain_pin)
repeat(14) {
last_chain=chain
chain=instance_create_depth(x,last_chain.y+16,5,obj_chain_part)
physics_joint_revolute_create(last_chain,chain,chain.x,chain.y,0,0,0,0,0,0,0)
}

Теперь вставляем объект obj_chain в комнату. Наша цепь готова! Кол-во звеньев можно регулировать, меняя значение в коде repeat (14) . Т.е. сейчас 14 повторений участка кода и соответственно звеньев. Можете уменьшать или увеличивать. Я еще создал событие столкновения в объекте корпуса машины со звеньями цепи. Чтобы, проезжая, машина задевала цепь в примере.

Реализация цепи и машины на Box2D в Game Maker Studio
Реализация цепи и машины на Box2D в Game Maker Studio

Думаю на этом стоит закончить урок. Для меня очень сложно было описать все вкратце. Но иначе этот урок было бы сложнее понять. По этому я постарался все разжевать подробно и понятным языком.

Спасибо, что дочитали статью до конца! Ставьте лайки, делитесь ей с другими, задавайте вопросы, оставляйте комментарии, пожелания и т.д. Удачи с изучением! Главное практика. Пробуйте, создавайте, экспериментируйте с различными параметрами и у вас все получится. Надеюсь этот урок окажется вам полезным.