Что такое коллизия в играх

от admin

Что такое коллизия в играх

Коллизия — это упрощенная геометрия, которая повторяет общую форму модели с меньшим количеством полигонов и создает возможность столкновений игрока с 3D объектами в игре. На нее требуется минимальное количество полигонов, отсутствие мелких деталей, определяется все это по принципу достаточности в каждом конкретном случае. Ее можно создать автоматически с помощью инструментов игрового движка, либо вручную. В некоторых случаях более подходящим вариантом будет создание вручную. В Unreal Engine 4 есть базовая утилита создания геометрии коллизии в Static Mesh Editor.

Самостоятельно коллизию можно создать двумя способами. С помощью примитивов в самом движке в разделе Static Mesh Editor — Collision, либо в 3D редакторе. При ручном создании, коллизия должна совпадать по имени с мешем для которого была сделана, обычно она имеет какие-либо дополнительные префиксы к основному неймингу, например, UCX_SM_Wood_Chair_A . Документация Unreal Engine приводит в пример следующие виды префиксов:

  1. UBX_имя объекта – при наличии коллизии в виде бокса без изменений.
  2. UCP_имя объекта – капсульная коллизия, представляющая собой цилиндрический объект с вершинами в виде полушарий. В ней не должно быть большого количества сегментов.
  3. USP_имя объекта – коллизия в виде сферы с небольшим количеством сегментов.
  4. UCX_имя объекта – сложная форма меша, не имеющая в себе разрывов, отверстий и внутренних углов.

Лучшим решением при создании коллизии является ее разбиение на простые примитивы, которым не желательно пересекаться между собой. Если коллизий несколько для одного объекта, они должны иметь уточнения в нейминге. Коллизия экспортируется вместе с основным мешем в один FBX файл (она может быть скрыта или видимой, это не имеет значения в технической работе коллизии при экспорте), расположение пивота у коллизии и меша должно совпадать и находиться в центре координат.

В выпадающем списке раздела Collision есть различные способы добавления коллизии. Первые три: Add Sphere/Capsule/Box Simplified Collision являются примитивами, которые можно редактировать с помощью пивота при нажатии на появившуюся сетку, кроме того, ее можно дублировать через Ctrl+D (Хоткей актуален для UE5, для UE4 — Ctrl + W). Следующие варианты идут с добавлением K-DOP. Это простые генераторы коллизии, где K – число плоскостей, проецируемых по выбранной оси (X, Y, Z).

  • 10 – бокс с 4 забевеленными эджами (гранями) по одной из осей.
  • 18 – бокс со всеми забевеленными эджами.
  • 26 – бокс со всеми забевеленными эджамии и углами.

Еще одним вариантом создания автоматической коллизии является Auto Convex Collision. Появляется панель Convex Decomposition, в которой находится три параметра:

  • Hull Count – общее количество примитивов.
  • Max Hull Vertex – общее количество вершин, которое будет иметь коллизия.
  • Hull Precision – коэффициент точности проекции коллизии.

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

Добавленную коллизию можно удалить через Remove Collision в выпадающем меню при нажатии раздела Collision.

Collision Pressets (коллизионные прессеты)

  • Default – используются параметры выставленные в Static Mesh Editor.
  • Custom – задаются пользовательские параметры для инстанса.
  • NoCollision – нет коллизии.
  • BlockAll – статический объект блокирует по умолчанию все Actor.
  • OverlapAll – статический объект при пересечении задает overlap событие по умолчанию все Actor.
  • BlockAllDynamic – динамический объект блокирует по умолчанию все Actor.
  • OverlapAllDynamic – динамический объект при пересечении задает overlap событие по умолчанию все Actor.
  • IgnoreOnlyPawn – игнорируется только объект типа Pawn (например, персонаж игрока).
  • OverlapOnlyPawn – задает при пересечении overlap событие только объектом типа Pawn.
  • Pawn – сам объект типа Pawn, который может использовать капсульную коллизию.
  • Spectator – объект типа Pawn, который игнорирует все статические Actor.
  • CharacterMesh – объект типа Pawn, который используется для персонажа.
  • PhysicsActor – Actor с симуляцией.
  • Destructible – разрушаемый Actor.
  • InvisibleWall – статический невидимый объект.
  • InvisibleWallDynamic – динамический видимый объект.
  • Trigger – динамический объект, используемый как триггер.
  • Ragdoll – SkeletalMeshComponent с симуляцией.
  • Vehicle – блокирует другой транспорт, статические и динамические объекты.
  • UI – статический объект, который перекрывает все Actor.
  • Project Default – задаются параметры по настройкам проекта.
  • Simple and Complex – в зависимости от запросов в сцене может быть использована простая и сложная коллизия.
  • Use Simple Collision as Complex – используется только простая коллизия.
  • Use Complex Collision as Simple – используется только сложная коллизия.
  • NoCollision – тело коллизии не будет видно и как-либо использовано в пространстве или симуляции. Является лучшим вариантом для оптимизации.
  • Query Only – используется для пространственных запросов. Подходит для движения персонажей и объектов, которые не нуждаются в физической симуляции.
  • Physics Only – подходит для физической симуляции (скелетная анимация и ограничения). Полезно в работе с вторичной анимацией, где не нужно обнаружение костей.
  • Collision Enabled –может быть использовано как для пространственных запросов, так и при физической симуляции.

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

  • WorldStatic – используется для неподвижных объектов. Параметр хорошо подходит для объектов с одноименным типом (например: пак коробок или бочек).
  • WorldDynamic – используется для Actor, которые могут быть подвижны под влиянием анимации или кода (например: лифт, двери).
  • Pawn – объекты, контролируемые игроком (например: персонаж).
  • PhysicsBody – объект перемещаемый благодаря физической симуляции.
  • Vehicle – транспорту задается параметр по умолчанию.
  • Destructible – разрушаемому объекту задается параметр по умолчанию.

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

Проработка окружения в геймдеве: собираем первую игровую сцену

Финальная статья из цикла «Арт» для начинающих разработчиков — наполняем деталями локации и полируем сцены.

Автор: Александр Новиков. По образованию программист, но в геймдев попал как концепт-художник. Потом переучился на 3D-художника и пришел в Pixonic. Работал над War Robots и другими проектами компании. Стал техлидом, и сейчас занимается прототипами игр.

В предыдущей статье о 3D-моделировании мы учились создавать уникальные внутриигровые объекты. Разобравшись с принципами создания арта, можно заменять им «серые кубики» из прототипа, чтобы потихоньку готовиться к первому релизу. Следующий этап — объединить объекты в одну сцену.

В конце статьи — последнее в этом цикле домашнее задание для конкурса работ. Выполните его, чтобы выиграть лимитированное издание Kingdom Hearts III PS4 Pro Bundle и прокачать скилл геймдизайнера.

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

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

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

Rise of the Tomb Raider

Пройдитесь по сцене — нет ли там слишком длинных и однообразных маршрутов, не кажется ли сцена слишком «пустой» местами?

Проработка окружения. Обратите внимание, какими предметами заполнены сцены в хорроре Alien Isolation. Трубы, решётки, дым, который отбрасывает пугающие тени от правильно расположенного источника света — всё это создаёт атмосферу страха, даже когда рядом нет противника.

Можно было бы поставить вместо решеток обычные стены, а источник света повесить под потолок. Или просто убрать все трубы и решетки. Окружающее пространство стало бы свободнее и лучше освещалось. Но страшно бы не было.

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

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

Например, важнее сначала разглядеть цель и противников, а не лежащий на полу лут. А факелы в подземелье, которые можно зажечь, должны быть видны даже в темноте. Всё это — акценты, чтобы визуальная информация помогала лучше ориентировался в мире игры.

Может показаться, что все элементы и объекты на скриншоте выше расставлены незамысловато. Но присмотритесь — маркер цели отлично читается на общем фоне, хотя это просто элемент UI. Общий фон не забирает на себя много внимания — он приглушен туманом и имеет минимальную контрастность. Ближний фон, наоборот, весьма контрастный. А ёлки, камни и платформа показывают понятный игроку путь до цели.

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

Свет. Он должен гармонично подчёркивать интерактивные детали на сцене. Кроме того, в играх свет часто устанавливается так, чтобы показывать дальнейший путь главного героя, как бы намекая куда двигаться дальше. Это работает, даже если игрок не осознаёт этого.

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

Обратите внимание на все интерактивные объекты на сцене — они должны быть отличимы от остальных. Стоит также прикинуть, что будет, если игрок не заметит их и просто пройдёт мимо.

Лаконичность. Не менее сложным бывает вовремя остановиться и не перегружать игровую сцену деталями. Когда объектов слишком много, игрок быстро устает от картинки.

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

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

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

Под цветом я имею ввиду палитры, которые используются в текстурах, преобладающие источники света (теплые или холодные) и цветокоррекцию. Например, на скриншоте ниже мы видим чистые светло-серые и тёмно-серые текстуры, спокойное нейтральное освещение и цветокоррекцию, которая даёт характерный зеленоватый оттенок.

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

Тестировать сцены и левел-дизайн так же важно, как идеи, механики и визуал. Для независимых разработчиков варианты собрать фидбек остаются теми же, что и в прошлых статьях: дать поиграть билд друзьям; завести свой YouTube-канал или странички в соцсетях, чтобы делиться ходом разработки и собирать комментарии; создать Discord-канал (или поискать чужие — там сидит много энтузиастов). Много фидбека можно собрать на Reddit, если не пугает английский, или на DTF.

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

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

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

Чтобы настроить лайтмэпы в Unity, раскройте вкладку Lightmaps в инспекторе объекта и нажмите на текстуре Open Preview. Откроется окно с общим лайтмэпом сцены, где жёлтым будет обозначен ваш пропс. Сразу видно, сколько места он занимает относительно других объектов.

Если встречаются артефакты в освещении или тенях, обязательно проверьте, что у объектов достаточно разрешения в лайтмэп-текстуре. В Unity за это отвечает параметр Scale In Lightmap. Дефолтное значение 1, а для малозаметных объектов можно поставить значение 0.5. Иногда, наоборот, приходится увеличивать это значение, когда свет запекается некорректно.

Здесь, подняв значение Scale In Lightmap c 1 до 1,6, мне удалось избавиться от «чёрного» камня после перепекания лайтмэпа.

После оптимизации ассетов, обратите внимание, чтобы не осталось белых засветов и полностью черных теней — это первые признаки несбалансированной картинки. В большинстве случаев объекты должны «читаться» даже в тени. Если какое-то пространство просто «залито» чёрным цветом, глаз воспринимает это как «провал» в окружении, как на примере с камнем выше.

Конечно, бывают исключения, особенно в 2D и инди-проектах. Всё зависит от вашего замысла.

Unepic. Темно, но тут своя атмосфера

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

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

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

Настраивать билды для мобильных платформ внутри движка лучше в начале или середине разработки, чтобы ошибки с компрессией текстур всплывали на ранних тестах. Но в процессе разработки не всегда получается настроить всё вовремя, поэтому перед финальным релизом необходимо пробежаться по контенту и всё проверить. Будет плохо, если где-то заваляется текстура маленького кристалла в разрешении 2k, а размер билда при этом вырастет на 5–10 Мбайт.

Итак, финальное задание на этот цикл, а приз — лимитированное издание Kingdom Hearts III PS4 Pro Bundle. Если вы уже выполнили задания из предыдущих статей, то будет совсем просто. Нужно вспомнить всё, что мы уже проходили, и собрать выполненные задания в одном письме:

  1. Опишите визуальную стилистику своего проекта и перечислите ваших ближайших «конкурентов». Сделайте мудборд. Здесь поможет первая статья цикла.
  2. Добавьте к письму уникальный концепт-арт или простой скетч любого объекта, персонажа или локации из игры. К концепту приложите ТЗ, по которому он рисовался. Это тема второй статьи.
  3. Покажите законченный 2D или 3D-объект, сделанный по концепту (можно скриншотами или роликом на YouTube). Говорили об этом в третьей статье.
  4. Дополнительный балл за собранную игровую сцену со своими оригинальными объектами. Тоже можно записать видеоролик.

Приём работ закроется 7 апреля в 23:00 по МСК — присылайте их на [email protected] . В середине апреля выпустим материал с итогами, подарим консоль и пойдём дальше — впереди цикл про маркетинг для инди-разработчиков. Будет интересно.

Для хитбоксов нет универсального решения — как устроена система регистрации столкновений в играх Статьи редакции

Журналист издания PC Gamer Алекс Уилтшир поговорил с несколькими разработчиками и узнал, как в играх реализуется система регистрации столкновений. Оказалось, что для каждого жанра подходит свой тип хитбоксов, который лучше всего соответствует геймплею и правилам. Мы выбрали из текста главное.

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

В разных играх работают разные правила, поэтому те решения, которые подходят для одной игры, могут всё испортить в другой. Тем не менее хитбоксы применяются в огромном количестве тайтлов: удары в Mortal Kombat, прыжок над пилами в Super Meat Boy, хедшот в Rainbow Six: Siege. Во всех этих случаях хитбоксы влияют на то, справился ли игрок с испытанием или нет.

Хитбоксы работают в обе стороны — всё же в столкновении принимают участие два объекта. Для этого существует понятие «хёртбокса» (hurtbox) — у кулака, бьющего противника, и пилы также существует невидимая геометрия, которая регистрирует попадание.

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

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

Такие хитбоксы отлично подходят для экшенов от третьего лица — это помогает пользователю понять, что именно происходит во время боя, и, следовательно, научиться играть.

В играх жанра shoot ’em up используется другой подход. Там хитбоксы обычно намного меньше, чем сама модель или спрайт игрока. Это помогает уворачиваться от огромного количества пуль, которые зачастую заполоняют весь экран. Если бы хитбоксы полностью соответствовали аватару, то такие игры были бы намного более трудными и менее приятными для прохождения.

Абстрактный музыкальный экшен Endlight использует традиционные для shoot ’em up хитбоксы. В Endlight у корабля есть три хитбокса, каждый из которых выявляет определённый тип коллизий. Хитбокс, который регистрирует столкновения со стенами, намного меньше корабля — это даёт большую свободу маневрирования. Хитбокс, анализирующий столкновения с ценными объектами, значительно больше аватара. Из-за этого игрок ощущает собственное мастерство.

Третий хитбокс издаёт свистящий звук, когда игрок пролетает мимо стен и препятствий. При этом у него есть два размера: один больше корабля в три раза, а другой — в десять. Первый предназначен для небольших объектов, а второй — для крупных. В результате маленькие препятствия свистят только тогда, когда они находятся рядом, а большие — когда находятся далеко.

В Disc Room также используются хитбоксы, которые прямо не воздействуют на результаты, но создают определённые эффекты. Например, когда игрок приближается к смертоносной пиле, он начинает легко трястись, появляется характерный свист с эффектом Доплера, а время немного замедляется.

Это говорит вам о том, что опасность рядом. Так игра даёт больше времени, чтобы отреагировать.

Мы хотим, чтобы захватывающие моменты случались как можно чаще. Гораздо лучше, если игрок совершит невозможное действие и выживет, чем погибнет от того, что казалось лёгким.

При этом хитбоксы в Disc Room используют ещё и временные показатели.

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

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

Разработчики из Metanet потратил целых десять лет на настройку и полировку хитбоксов для своей серии платформеров N. Например, работа над хитбоксами продолжалась даже в последние недели создания N++. Именно тогда увеличились хитбоксы предметов, которые нужно собирать, и уменьшились хитбоксы опасных объектов.

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

Несмотря на название, хитбоксы — это не всегда «боксы». В то время как хитбоксы в Dark Souls, Monster Hunter World и Apex Legends повторяют форму персонажей, в играх других жанрах они бывают самыми разными: сферы, ромбы и так далее.

В файтингах по-прежнему используются квадратные хитбоксы, которые появились ещё в Street Fighter 2. Но есть и исключения — например, Marvel vs. Capcom, в которой используются круги. А в 3D-файтинге Mighty Fight Federation применяются сферы и кубы.

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

В платформерах хитбоксы обычно круглой формы. Например, N++ благодаря этому ощущается лучше, потому что герой не цепляется за острые углы. Это позволяет легко перемещаться по уровню.

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

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

В Endlight на экране одновременно присутствует множество объектов, поэтому разработчику Джиму Макгинли пришлось оптимизировать игру. Он сократил количество проверок неподвижных объектов и проигнорировал объекты, которые находятся далеко от пользователя. Поскольку это рельсовая игра, Макгинли знает, что каждый объект прилетает к игроку через 20 секунд после спауна. Именно поэтому хитбокс появляется у них только через 18 секунд после появления.

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

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

Ммм, лучшая сторона DTFа,)

Мы же не на подсайте о порно

Статья пустая, надо было писать то как хитбоксы соотносится с видимой моделью в сетевых баталиях. Примеры left 4 dead 2, cs, overwatch и прочее. В этих играх, же победа у того кто лучше видит хитбоксы, а не реальную модель.

Пример того, анализ чего я хотел увидеть в статье

Читать:
Asus download license что это

Хитбоксы обсуждаете, а мемы не мемите

Вот это имя я не слышал уже очень много лет.
Спасибо, пойду наковыряю где-нибудь оригинальную N и сяду переигрывать.

Оригинальная ещё на flash была 🙂

Не, ну это откровенно тупо

В целом статья хороша

Или еще пример — решил на днях посмотреть что за зверь такой этот TES Morrowind, о котором часто слышу много хорошего.
И в первой же стычке с врагом. не попадаю по нему мечом, при том что стою в упор и махаю без перерыва. Вернее попадаю но проходит одна атака из 5 примерно. Сижу в ступоре и не понимаю куда нужно бить и когда чтоб атака засчитывалась, но, судя по всему в морровинде используется система с шансом попаданий и шанс попадания равен навыку владения оружием. То есть если у тебя навык владения 10, то 9 из 10 атак уйдут в молоко, даже если по модельке ты попал. И вот не понятно — толи ты попал по врагу, но игра засчитала "промах" то ли не попал по модельке — сиди гадай — приятного в этом мало

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

Просто все хорошие разработчики игр знают кучу приемов, для хорошей реализации.

Хах, в 2018 году на чемпионате Quake Champions во время дуэли ракета пролетела буквально между ног у модельки персонажа и ход боя поменялся в корне — все участники сразу стали требовать у разработчиков вернуть классические "капсульные" хитбоксы вместо тех, которые точно повторяют видимые модели.

Реплай для всех:
Я не доволен тем, как построено предложение. Хитбоксы нужны для регистрации попаданий, а не для удовлетворения игрока. Нет хитбокса — нет регистрации. Тут скорее "почему хитбоксы не всегда соответствует моделе" или что-то вроде этого

А разве нет? Спорил тут с парнем по поводу хитбоксов в Mortal shell — он привел в пример момент, когда визуально гг не попал по врагу из-за того что враг попал в капкан и был в соответствующей анимации "обездвиживания"
Было бы честно если бы удар по обездвиженному врагу, которого ты заманил в капкан не прошел из за анимации высвобождения из этого самого капкана? По моему нет — игрок все просчитал и сделал верно, а наказание за то что враг пошатывался в анимации обездвиживания вызвало бы крайнюю степень фрустрации и ощущение рандома и несправедливости

И ни слова о SF5 с обложки, где много хохм с хитбоксами.

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

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

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

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

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

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами ⁠ ⁠

Как было сказано в прошлом посте, игра, которая будет сделана в ходе данных гайдов, будет относиться к жанру стратегий, а в качестве источников для «вдохновения» у нас — «Oxygen Not Included» и «Rimworld«. Теперь же конкретно поговорим с вами о том, что в игре должно быть реализовано, по пунктам.

—) Персонаж — игровой «объект», способный перемещаться по игровому миру и взаимодействовать с ним. Делятся на подконтрольных и неподконтрольных игроку. Игрок НЕ имеет прямого управления над своими подопечными, кроме специального «боевого» режима.

—) Каждый персонаж должен иметь или уметь следующее:

—) Взаимодействовать с предметами, расположенными на карте: подбирать их в свой инвентарь или выкладывать; взаимодействовать с рабочими станциями; сражаться (наносить, получать урон).

—) Каждый персонаж смертен. Каждый персонаж должен иметь ряд характеристик, которые он будет пытаться «поддерживать» на должном уровне, чтобы не умереть и продолжать быть эффективным. Эти характеристики:

—) Каждый персонаж уникален и должен отличаться от других. Черты, навыки с различными уровнями прокачки. Этот пункт может игнорироваться в случае, если это не подходит под конкретного персонажа.

—) Объекты, с которыми можно взаимодействовать через интерфейс игры и с которыми могут взаимодействовать персонажи или иные игровые сущности с какой-то целью.

—) Пример: верстак для создания вещей; исследовательский стол для открытия новых вещей и пр.

-) Интерфейс.
—) Простой, понятный. Желательно, на русском языке.
—) Хотя бы минимально настраиваемый.

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

Сейчас — продолжаем изучать матчасть.

События отрисовки.

Событие отрисовки добавляется на объект как и любое другое, через кнопку «Добавить событие (Add Event)».

Имеется два события:

—) Событие, которое отрисовывает объект в комнате.

—) Событие, которое отрисовывает объект на экране.

Иными словами, событие отрисовки GUI позволяет нам закрепить на экране наш интерфейс и то, что мы хотим игроку показывать всегда. Draw — стандартная отрисовка.

Возникает вопрос: зачем нам отдельно добавлять событие отрисовки, если объект спокойно отрисовывается и без него?

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

Если вы добавили событие отрисовки, то вам необходимо написать в коде следующую строку:

В противном случае, объект не будет отрисован.
Проделайте это сами. 🙂

Итак. Что мы можем делать в событиях отрисовки:
-) Отрисовка спрайтов:
—) draw_self() — отрисовывает спрайт текущего объекта с настройками по умолчанию.
—) draw_sprite_ext( название спрайта в обозревателе, номер изображения, x, y, x-масштабирование, y-масштабирование, поворот, цвет, прозрачность) — отрисовка спрайта «расширенная» — т.е. с настройками. Можно отрисовать любой спрайт, как и везде, где его нужно отдельно указывать.

—) draw_sprite_part(название спрайта в обозревателе, номер изображения, x координата левой верхней точки спрайта, y координата левой верхней точки спрайта, ширина, высота, x, y) — отрисовка части спрайта
—) draw_sprite_stretched(название спрайта в обозревателе, номер изображения, x, y, ширина, высота) — отрисовка спрайта с его «растяжением». Если у спрайта включить и настроить функцию Nine Slice (девять «срезов»), то можно создавать масштабируемые (с одинаковым разрешением, пропорциями и качеством по итогу) элементы интерфейса: окошки, кнопки, etc.

-) Отрисовка фигур:
—) draw_circle(x, y, радиус, заполнение (True/False)) — рисуем круг. Аналогичное есть для прямоугольника (rectangle), стрелки (arrow), эллипса (ellipse), линии (line).
—) draw_button(x, y, x2, y2, up) — Отрисовка кнопки. Где up — True или False, нажата кнопка или нет.

-) Настройки отрисовки.
—) ВАЖНО. Любые настройки отрисовки нужно проводить ПЕРЕД отрисовкой. Можно делать в любом событии, но для удобства лучше тут же.
—) draw_set_color(col) — устанавливаем цвет отрисовки. Базовые значения цветов начинаются с приписки «c_». Пример: c_black, c_red.
—) Для продвинутых — можно использовать HEX, как в CSS: #11CCFF как пример. Используется стандартная RGB система. Если заменить решётку на $, то система сменится на BBGGRR, т.е. наоборот.
—) draw_set_alpha(alpha) — прозрачность отрисовки
—) draw_set_font(font) — устанавливаем шрифт
—) draw_set_halign(halign) — Расположение текста по горизонтальной оси (fa_ left/center/right)
—) draw_set_valign(valign) — Расположение текста по горизонтальной оси (fa_ top/middle/bottom)

Это та часть, что касается кода и с которой мы с вами будем непосредственно работать. Можете держать как памятку у себя перед глазами, когда начнём писать код.

Коллизия — иначе говоря, столкновение объектов, происходит благодаря «маске» спрайта. Если спрайт — это картинка объекта, то маска — это «твёрдое тело», отвечающее за считывание столкновений.
Чтобы её посмотреть, откройте настройки спрайта и разверните пункт «Collision Mask«

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

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

Mode — режим маски. Варианты:
— Автоматическая
— На всё изображение
— Ручная

Type — тип маски. Варианты:
— Прямоугольник
— Прямоугольник с поворотом
— Эллипс (работает медленнее)
— «Алмаз» (ромб) (работает медленнее)
— Предрасчет / Точный (медленнее) — ГМС постарается сам подстроить маску под форму объекта.
— Предрасчет / Точный по кадрам.

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

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

Как работают скрипты.

Скрипт (функция) — именованный блок кода, выполняющий определённую задачу.
Все команды, которые мы использовали до этого, являются такими «скриптами». Иногда я буду называть их функциями, оба варианта правильные.

Создать скрипт просто. Для этого нажмите ПКМ по папке «Scripts» и выберете там «Script«. Назовите его scrMove
У вас откроется следующее окно:

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

scrMove — название нашей функции. В круглых скобках мы в неё можем передавать аргументы. Аргумент — это переменная, которая используется только в функции, передаётся в неё при вызове и может иметь любое название. В скобках напишите spd — это будет как раз наша переменная скорости.
Вырежьте код движения из Step-события у игрока и вставьте в скрипт, а в Step-событии игрока напишите следующий код:
scrMove(player_speed);

Получится следующая картина:

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Как вы заметили, «x» и «y» у нас по прежнему работают. Это потому, что мы выполняем скрипт в объекте oPlayer: данные переменные подтягиваются из объекта автоматически.

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

Для того, чтобы скрипт вернул какое-то значение, нужно написать:

Переменную можно написать только одну. Команда return прерывает выполнение скрипта. Переменную / возвращаемое значение можно не писать, тогда скрипт просто прервётся.
Конструкцию с прерыванием следует добавлять везде, где это может повлиять на игру, особенно её работоспособность.

Раньше скрипты выполнялись медленнее, чем код, написанный просто в объекте. Сейчас это не так (или, по крайней мере, не так критично).

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

Скрипт для отрисовки текста с обводкой.

Создаём новый скрипт и называем его scrOutlinedText
Нам понадобятся следующие аргументы:
-) xPos — позиция текста по X
-) yPos — позиция текста по y
-) col — цвет текста
-) outlineCol — цвет обводки
-) text — текст
-) curdepth — текущая «глубина» объекта.
-) Шрифт, которым будем рисовать.
-) Позиционирование по X
-) Позиционирование по Y

Общая схема работы скрипта:
1) Назначаем максимальную «глубину».
2) Рисуем текст цветом обводки.
3) Поверх рисуем текст нужным нам цветом, но с небольшим смещением.
4) Возвращаем глубину к первоначальным показателям.

Код:
https://pastebin.com/TahYZKc8
P.S.
Изначально код не мой, а честно стырен подсмотрен с интернета, но я в него добавил больше переменных для лучшей настройки и отрисовки. Фактически, значение глубины тоже можно передавать как аргумент, чтобы разный текст выводился по разному.

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Создание русского шрифта

Проверим, как работает скрипт.
Сначала мы создадим русский шрифт. Для этого найдём папку «Fonts«, нажмём ПКМ и создадим «Font«.
Выбирайте любой шрифт и размер, который хотите. Нам с вами нужна кнопка «Add«, чтобы добавить диапазон с русским шрифтом.

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Здесь напишем 1040 to 1105, чтобы захватить весь русский алфавит, затем нажмём «Add Range».
Шрифт называйте на Ваше усмотрение. Я назову его: fontArialRusSmall

Теперь перейдём к объекту игрока. Создадим событие Draw GUI и напишем следующий код:
scrOutlinedText(10, 10, c_yellow, c_red, «Скорость: » + string(player_speed), depth, fontArialRusSmall, fa_left, fa_top)

Результат:

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Можете заменить c_yellow и c_red на любые цвета. Помните, что можно передавать цвета в HEX с помощью # и $ (в обратном порядке).

Скрипт для поиска значения в массиве:

Так как эту тему мы не проходили, заострять внимание не буду, но вдруг кому пригодится:
https://pastebin.com/1VTNg4Bp

Переходы между комнатами. Создаём меню.

Наконец, с матчастью мы закончили. Приступим к тому, что создадим меню нашей игры.
Создаём новую комнату и обзываем её rmMainMenu. Затем нажмите на значок «домика», чтобы поменять стартовую комнату (ту, что отображается при запуске игры).

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Сделайте так, чтобы домик был напротив созданной комнаты.
Заметьте, что при создании новой комнаты у неё изменяются все настройки! Это важно.

Создадим в «Objects» папку «Меню«, где создадим следующие объекты: «oMStart«, «oMSettings«, «oMExit«, «oMMenu«.
OMStart — кнопка для старта нашей игры.
OMSettings — кнопка для перехода в настройки игры.
oMExit — кнопка для выхода из игры
oMLoad — кнопка для загрузки игры
oMMenu — управляющий объект, который будет располагать наши кнопки.

Зайдём в комнату MainMenu и поставим там объект oMMenu.
Затем перейдём в код oMMenu и выберем событие создания (Create)

Там напишем следующий код:

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

У каждого объекта создадим два события: Draw, которое оставим пустым, и Draw GUI, где напишем draw_self();
Там же напишем:

Где «Здесь текст кнопки» — заменить на нужное: «Начать игру«, «Загрузить игру«, «Настройки«, «Выход«

Вернёмся в OMMenu.
Нажмите правой кнопкой мыши. Наведитесь на пункт «Code Snippets» и выберите пункт 5.
В данном меню расположены готовые шаблоны кода, а мы создали шаблон цикла.
Напишите следующий код:

for (var i = 0; i < array_length(buttons); ++i)

<

instance_create_layer(room_width / 2, room_height / 2 — 50 + sprite_get_height(sButton) / 2 + 100 * i, «Instances», buttons[i])

>

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Теперь нужно сделать отслеживание нашей мышки. Кнопку «Настройки» мы сделаем чуть позже. Пока перейдём к кнопке для выхода из игры.

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

ОК. Теперь мы отслеживаем нашу мышку относительно GUI. Нужно проверить, наведены ли мы на конкретный объект и если да — нарисовать поверх него полупрозрачный белый прямоугольник. Для этого есть команда:
instance_position(x, y, obj)

В x и y мы передадим переменные выше, а в качестве объекта напишем «self«, чтобы проверять координаты нашего объекта.

Уже после этого пишем наш текст.
Теперь при наведении на кнопку «выхода» мы увидим, что она «активна».

Вырежем наши две переменные, добавим их в событие create. Теперь мы можем использовать эти переменные в любом коде этого объекта.

Теперь перейдём в событие step. Сюда также добавим наши две переменные. Теперь они будут постоянно обновляться.
Начнём настраивать логику работы.

Можете скопировать тот код, что мы писали выше, но удалить всё изнутри.
Нам нужно сделать проверку:
Если мы наведены на объект И нажата левая кнопка мыши — выйти из игры. То есть, немного её дополнить.

Для проверки нажатия кнопки левой мыши будем использовать команду:
mouse_check_button_pressed(mb_left)
Для выхода из игры:
game_end()

В итоге, в коде step будет следующий код:

Итого, если мы наведёмся на кнопку выхода — она подсветится. Нажмём — игра закроется.

Аналогичный код с подсветкой и проверкой просто скопируем в oMStart. В других кнопках логику работы в step пока не настраиваем на них, работаем с кнопкой начала игры.
Нужно внести одно изменение.

Вместо game_end() нам нужно написать код для смены уровня.
Для этого напишем:
room_goto(Room1)
Где Room1 — название комнаты, в которую вы хотите переместиться. Оно должно совпадать с названием комнаты в браузере ассетов.

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

Для этого нам придётся создать новый объект и назвать его oGameManager.
Разместим его в самой первой комнате и отметим у него чекбокс «Persistent«
Затем напишем у него в Step код:

Если индекс текущей комнаты != 0 и нажата ESC — деактивируем все инстансы, кроме текущего и переходим в меню.

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

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

Реализация сложнее. О том, как работает Nine Slice.

Ниже будет приведена реализация меню с использованием функции Nine Slice, которая позволит нам делать кнопки других размеров.
Используя Nine Slice мы не сможем проверять, наведены ли мы сейчас на нужный нам объект. Также эта функция годится только для отрисовки типовых форм с типовым шрифтом. Если у вас спрайт кнопки идёт с текстом, то данная функция не подойдёт.
Чтобы отслеживать нажатия и наведение, нам необходимо проверять, находятся ли координаты мыши в нужной области. Для этого существует команда

Итак. Первый шаг — это убрать спрайт у каждой нашей кнопки.
Для этого откроем объект каждой кнопки, нажмём на выбор спрайта и выберем «None«.

Шаг второй.
У каждой кнопки в событии Create мы пропишем:

При создании кнопок мы и так будем знать их x и y координаты, а ширину и высоту будем передавать.

Шаг третий
Нарисуем спрайт в виде одноцветного квадрата размером 9х9 пикселей.
Затем добавим ему две обводки разных цветов, каждая шириной в 1 пиксель.
Получим следующую картину:

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Теперь перейдём в настройки спрайта.
Назовём его sButtonSlice.
Слева выберем и откроем пункт Nine Slice.

После чего поставим галочку «Activate Nine Slice«.
Далее — смотрим на наш спрайт и настраиваем его, как показано на скриншоте ниже:

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок

Чтобы двигать фиолетовые полоски — достаточно на них навестись и зажать ЛКМ.
В правом окошке вы можете порастягивать данный спрайт, как хотите и посмотреть на итоговый результат.
Растягивающаяся рамка для кнопок готова!

Шаг четвертый.

Пропишем в Draw GUI отрисовку кнопки вместо draw_self():

Таким образом, мы отрисовываем кнопку.

Вернёмся в oMMenu, в Create, где немного допишем наш код.
Мы создадим переменную, которой будем присваивать значение ID только что созданного объекта. Затем, обращаясь к этой переменной, мы будем менять у данного объекта параметры: ширину и высоту.

Меняя значения bwidth и bheight вы сможете сами настроить нужные размеры кнопок.

Обратите внимание, что создавая инстанс мы можем передать struct — то есть структуру данных.
Тогда не нужно будет обращаться к инстансу через переменную, но придется удалить код

При создании наших объектов, а сам код для создания инстанса преобразится следующим образом:

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

Теперь задача — сделать так, чтобы мы могли считывать, наведены ли мы сейчас на кнопку.

Для этого мы берём координаты x и y, после чего проверяем, находится ли наша мышь в области:

Остальное — копируем из прошлого кода. Получается следующий блок:


Шаг седьмой.

Проделать тоже самое в событии Step. (По сути, просто заменяем instance_position)


Шаг восьмой.

Донастраиваем все кнопки.

Какой из вариантов использовать — решать Вам.

Можно вообще использовать следующий вариант:

Создать спрайт нужных размеров и залить его белым цветом с «прозрачностью» в 1 единицу. Совершенно незаметно. Используя bbox_left / top / right / bottom нарисовать поверх прозрачной основы кнопку и проверять уже не через «point_in_rectangle», а как в первом способе.

На этом сегодняшний гайд подходит к концу.
Вкратце мы разобрали события отрисовки; как с ними работать; как работать со скриптами; как работать со шрифтами; а также вы можете смело скопировать себе и использовать несколько других скриптов в своих проектах.

Что нужно подготовить к следующему гайду:
— Минимум два спрайта «породы» — на фон (темнее) и для объекта (светлее). Размер одного спрайта — 32х32.
— Желательно спрайты нескольких объектов, вроде стен, дверей. Исходите из того, что размер одной клетки будет равен 32х32 пикселей.
— Спрайт для неба/космоса/прочего на фон на ваше усмотрение.

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

И небольшой спойлер на будущее.
Взаимодействовать с миром можно будет двумя способами: через ЛКМ и наведением «тела» игрока на тот или иной объект.

Загрузить файл проекта и всё пощупать самому можно по ссылке:
Яндекс диск

— Камера и её настройка. Разные способы реализации: от простого к сложному.

— Иерархия объектов. «Объекты-родители» и их «дети». Решение часто встречающихся проблем и немного про то, как удобно выстраивать взаимодействие с объектами. Глобальные переменные.

— Массивы и с чем их едят, а также grid (сетка комнаты), размещение объектов по сетке. Включая объяснение, в каких случаях лучше использовать встроенные функции, в каких – писать свои с нуля.

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

— Иные способы хранения информации в GMS2, когда их стоит или не стоит использовать.

— Сохранение. Встроенное VS самописное.

Есть вопрос — задавай, постараюсь ответить.
Что-то не получилось, вылезла ошибка и так далее — тоже пиши, помогу или поможем.

Похожие статьи