Pull to refresh

Tower Defense + Box2D

Reading time4 min
Views11K
Если бы вы писали Tower Defense игру, пришло бы ли вам на ум воспользоваться для этого физическим движком, например Box2D? Как бы вы реализовали движение юнитов, поведение башен? Что еще полезного вы бы извлекли из физического движка в такой игре?

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

Я большой поклонник Tower Defense игр. Все начиналось давным-давно с Green TD, карты для Warcraft 3, потом я перепробовал много игр на flashtowerdefense.com, а после того, как появился андроид смартфон, часто проводил время за играми из маркета.

Идея


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

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

Я сделал пять видов башен:

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

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

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

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

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

Box2D


Должен признаться, движок Box2D значительно облегчил мне жизнь. Благодаря ему у меня в игре было красивое падение фруктов, обнаружение их башнями а также другие проверки на столкновения. Без Box2D не было бы медведя. У меня есть несколько идей для новых башен, использующих физический движок, например лиса со стрелами, которые привязаны веревкой к ветке, если такая стрела попадет во фрукт, он будет болтаться на веревке, пока его не разобьют другие башни. Можно придумать еще очень много интересного.

Далее я опишу, в каких именно объектах я использовал Box2D, и какие свойства необходимо было задать:
Название Свойства Box2D Изображение
Фрукт b2CircleShape
b2_dynamicBody
groupIndex = -1
Ветка b2_staticBody
b2PolygonShape
Башня b2_staticBody
b2CircleShape
isSensor = true
Стрела b2_dynamicBody
b2PolygonShape
isSensor = true
Камень b2_dynamicBody
b2CircleShape
Стены, пол,
потолок
b2_staticBody
b2PolygonShape

b2_staticBody означает, что объект неподвижен, на него не действует гравитация и другие силы. Это относится к башням, веткам и границам.

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

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

b2CircleShape объект имеет круглую форму, b2PolygonShape — форму многоугольника, в моем случае все такие объекты — прямоугольники.

Должен признаться, что внедрерие Box2D в Tower Defense игру было не простым делом, я столкнулся со множеством проблем, например кто-нибудь из вас догадывается, как с помощью Box2D реализовать замораживающую башню? (на самом деле ответ на этот вопрос требует решения задачки 9-го класса по физике и заслуживает отдельного поста). Немалое количество времени потребовалось, чтобы подобрать подходящие физические параметры для всех объектов. Но в итоге все получилось, и я могу с уверенностью сказать: «Tower Defense + Box2D = Yeah!»

Результат


Я назвал свою игру Forest Tower Defense и выложил на андроид маркет. Желающие могут скачать ее бесплатно. Там же можно посмотреть скриншоты и видео к игре. Графика получилась мультяшная, поэтому детям игра тоже может понравиться.

Всем любителям Tower Defense игр я советую попробовать, ведь это единственная игра такого жанра с подобной механикой.

Мне очень интересно услышать ваше мнение, советы по улучшению и идеи новых фич.

UPD: Разработка игры велась по принципу, описанному в этой статье, поэтому есть версия для Windows с использованием Qt.
Tags:
Hubs:
+45
Comments43

Articles