Mushroomer. Взгляд изнутри, игровая физика

Ну что же, я наконец-то рассказываю подробно о том, как устроенна игра «Mushroomer», и на чем держится весь игровой мир милых и злых грибов вместе с голубыми гоблинами и огненными драконами. Не смотря на всю сложность и необычность игры, на самом деле все до безобразия просто.

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

Последний раз я работал над игрой аж 22 ноября прошлого года. Поскольку времени уже прошло много и я успел подзабыть, что и как работает, то работу я начал с рефакторинга кода. Ковыряясь в коде, я вспомнил о том, что я обещал по подробнее рассказать о том, как устроен Грибник внутри.

Скриншот игры с отладочной прорисовкой

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

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

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

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

Как видно на скриншотах, боксы отличаются цветами. В моем случае это сделано лишь для того, чтобы я мог отличать какой бокс за что отвечает. При этом они не имеют каких-то своих уникальных свойств. Цветовая легенда:

 

  • Зеленый — статические непроходимые объекты;
  • Оранжевый — динамические непроходимые объекты;
  • Розовый — датчики реакции/проверки;
  • Синий — статические датчики.

 

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

 

  1. Это уши убегающего гриба, ими он нащупывает приближающегося игрока и делает ноги.
  2. У моста тоже есть ухо, когда с ним пересекается какой-либо из динамических объектов, мост прогибается, как-будто от веса этого самого объекта.
  3. Это датчик персонажа, он нужен чтобы проверить наличие объекта, по которому можно ударить кувалдой, а так же он проверяет тип объекта. Например если это камень, то в момент удара будут произведены необходимые действия.
  4. Этот датчик проверяет не помешает ли что-нибудь удару по месту под номером 3. А так же он проверяет наличие в этом месте монстра, чтобы в момент удара его замочить.
  5. Этот датчик предназначен для проверки и удара по маленьким камням сбоку.

 

 

  1. Датчик зрения гоблина для поиска приближающегося игрока. Не работает со спины, но зато со спины работает датчик под номером 3 — если игрок касается этой зоны, то гоблин разворачивается и пытается его ударить (симметричный датчик).
  2. Зона удара гоблина, все объекты, которые попадают в эту зону, могут подвергаться удару (симметричный датчик).
  3. Датчик, определяющий землю под ногами при движении, он не позволяет падать гоблину в ямы (симметричный датчик).
  4. Этот датчик-пипка, нужен для определения активной зоны магического источника, когда он попадает в активную зону источника, камень поднимается вверх. А еще у маленьких камней есть снизу и в центре какие-то датчики, если честно я уже не помню зачем они нужны, но помню, что как раз с этими камнями было больше всего возни и без вспомогательных датчиков не получалось реализовать правильное поведение.
  5. У больших камней все проще, но они так же не обделены датчиками-пипками, которые работают в паре. Только при условии, что оба этих датчика попадают в активное поле источника, камень начинает всплывать.

 

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

 

  1. У злого гриба меньше датчиков, чем у гоблина, потому что по задумке это более тупое создание :) У него от гоблина осталось только зрение.
  2. Эти оранжевые датчики есть у игрока, грибов и у гоблина с драконом. В отличии от физического тела, они помогают живности определять, с какой стороны препятствие и как выравнивать эту саму живность относительно препятствия, а так же помогают разворачиваться монстрам в правильном направлении.
  3. Это та самая магическая сила источника, которая действует на датчики камней и персонажа.

 

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

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

 

художник написавший свой физический движок гений ;)

o_OOO
10 Марта 2010
— 19:13
#

Класс!!!Супер статья!!!

Руслан
10 Марта 2010
— 19:14
#

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

VirtualMaestro
10 Марта 2010
— 19:19
#

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

Кирилл
10 Марта 2010
— 20:35
#

Нечто подобное на хитри.сом было (я о модели столкновений ) А вообще графика на высоте жду релиза :)

?ван
10 Марта 2010
— 21:18
#

Очень познавательно!)
Немного не по теме: мне вот интересно, в Грибнике обновление (расчёт столкновений, отображение и т.д...) идёт каждый кадр (Event.ENTER_FRAME) или через промежуток времени? (Timer+DeltaTime). Какой способ Вам кажется удобнеелучше для Flash-игр жанра "платформер" (в большинстве случаев)?
Если вопрос слишком бредовый, проигнорируйте :)

Qwerty47
10 Марта 2010
— 22:08
#

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

Ant.Karlov
11 Марта 2010
— 02:05
#

@Кирилл, я писал о том как я с ним познакомился и как я его изучал, эта тема затрагивается в двух записях «Как я познакомился с Flash» и «Зомбошутер. ?ли как быстро освоить AS2?». ?зучал я его не долго, основной задачей было понять как все взаимодействует. От AS2 я был в тихом ужасе, но из-за всех его недостатков я очень быстро разобрался в том как все устроено. Позже я начал разбираться с AS3 и благодаря тому, что AS3 это уже более полноценный язык нежели AS2 — разбор пошел быстрее, поскольку у меня уже был программерский опыт в других очень похожих языках (delphi, php, js). С основами AS3 разобрался в течении нескольких недель, а далее начал практические занятия как раз с игры Mushroomer — ровно год назад :)

Ant.Karlov
11 Марта 2010
— 02:19
#

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

Ant.Karlov
11 Марта 2010
— 02:23
#

@Qwerty47, отображение безусловно идет каждый кадр, а далее игровые расчеты делятся на два вида: приоритетные — они рассчитываются каждый кадр. Например, действие гравитации, применение скорости и проверки жизненно важных «датчиков» на столкновения и последующая их обработка. ? не приоритетные расчеты, которые обрабатываются всего 4-6 раз в секунду, как раз аналогичным способом, как ты написал. В не приоритетные задачи входит проверка соприкосновения персонажа с сундуками или грибами, реакция злых грибов, гоблинов и драконов на персонажа ну т.п. То есть все то, что не зависит от частоты кадров и может выполнятся реже и при этом не заметно для игрока. Все это, кстати, тоже неотъемлемая часть оптимизации игры :)

Вопрос хороший, спасибо!

Ant.Karlov
11 Марта 2010
— 02:33
#

2Ant.Karlov:
Спасибо за ответ!
Очень интересная реализация, я бы до такого не додумался :)
Поскорей бы поиграть в Грибника :)

Qwerty47
11 Марта 2010
— 11:30
#

@Ant.Karlov
Значит нужно дочитывать Мука и браться за практику. Спасибо за ответ. ;)

Кирилл
11 Марта 2010
— 15:12
#

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

Lost
12 Марта 2010
— 11:59
#

@Lost, существует несколько различных способов хранения уровней в игре. Хранение уровней где-то в ?нтернет и их подгрузка во время игры — это не самый хороший вариант и годится только в тех случаях, когда редактор уровней отдается в руки игрокам. Уровни лучше всего хранить в самой игре. В игре Mining Truck уровни хранятся прямо в клипах, а в Mushroomer уровни хранятся, грубо говоря, в массивах :)

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

Ant.Karlov
13 Марта 2010
— 03:42
#

@Ant.Karlov
а в Mushroomer уровни хранятся, грубо говоря, в массивах :)
А собственно в каком виде этот массив сохраняется из редактора для последующей подзагрузки в игру?)

Lost
13 Марта 2010
— 13:43
#

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

Lost
13 Марта 2010
— 13:46
#

Все не так и просто...

CHLameR
14 Марта 2010
— 00:05
#

А где поиграть можно?

shaman4d
31 Марта 2010
— 12:01
#

@shaman4d, игра Mushroomer еще в разработке. Возможно через неделю другую игра будет доступна на FGL.

Ant.Karlov
2 Апреля 2010
— 01:57
#

я на 23 уровне, все пропало..., уже не могу пройти 2 дня, меня постоянно убивают 2 дракона, и вот уже нервы на пределе , а пройти не могу, что мне делать)))

Яна
16 Июня 2010
— 18:32
#

@Яна, на 23 уровне с драконами нужно делать примерно тоже самое, что и с драконами на предыдущих уровнях — уворачиваться и скидывать на них камни :) Но есть маленький секрет: дракона можно убить кувалдой ударив его в тот момент когда он спускается к вам, то есть удар нужно произвести когда вы фактически находитесь под драконом.

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

Ant.Karlov
20 Июня 2010
— 08:43
#

Мне очень нравится ваш выбор цвета. Как вы выбираете их? любой окраски советы?

koрнecx
6 Августа 2010
— 18:44
#

Я имею в виду, где вы получили все эти красивые цветы от? У вас есть кулуару схем? Мне очень хотелось бы использовать их в своих проектах

koрнecx
7 Августа 2010
— 00:02
#

@koрнecx, к сожалению я не пользуюсь цветовыми схемами и поэтому не могу ими поделится. Цвета в своей графике я подбираю интуитивно, так чтобы самому нравилось :) А еще часто просматриваю различные картинки других художников где иногда встречаю и обращаю внимание на интересные сочетания цветов, которые потом иногда пытаюсь подобрать в своей графике.

Ant.Karlov
7 Августа 2010
— 01:33
#

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

Annie
24 Марта 2013
— 17:52
#

Annie, я здесь по той же причине :)), 23 пройти невозможно, ...уже все неприличные слова употребила при прохождении этих драконов :), переживаю за сохранность компьютера, ругаюсь на клавиши, что они так медленно нажимаются :)
Уже ищу форумы, где может посоветуют как их пройти, докатилась :)), а ведь началось просто с помощи 3- летнему ребенку пройти 1 уровень...

Elena
28 Марта 2013
— 09:30
#

@Annie и Elena, вот ссылка на видео прохождение — воспроизвденение должно начаться как раз с начала 23го уровня. Надеюсь что тактика прохождения драконов будет понятна из видео :)

Спасибо за отзывы! Рад, что вам игра понравилась :)

Ant.Karlov
28 Марта 2013
— 19:31
#

Йеееес, я прошла 23 -ий! не так как на видео, но мне удалось!:) Ant.Karlov, спасибо за ссылку!:)

Elena
29 Марта 2013
— 20:54
#

За ссылку спасибо, но я уже просмотрела не одно видео с прохождением игры и драконов в частности)) вчера всё-таки прошла, хотя и не так совсем, одного убила кувалдой, а второго просто проигнорировала, удалось мимо прошмыгнуть))) и за час-полтора прошла остальные 7 уровней, всё-таки эти драконы - это нечто...)))
Ant.Karlov, спасибо за отклик, очень радует, что Вы так оперативно отвечаете)))

Annie
31 Марта 2013
— 13:10
#

@Annie, здорово! :)

К сожалению отвечать оперативно получается не всегда, но я стараюсь, да :)

Ant.Karlov
1 Апреля 2013
— 19:21
#