Раннер под iOS с пятью персонажами

Привет, хабр! Так случилось, что я довольно давно занимаюсь разработкой под iOS, но вот незадача — никогда не писал игры. После змейки в 13 лет под IBM 386 наступил перерыв до 2014 года, когда я набрался сил воплотить теплую ламповую мечту в реальность. Что из этого получилось? Графика сводилась так: 98227a7c32524ea3a2ca68847eeff561.gifА геймплей хотелось сделать похожим на это: 356d20ed05f2be64f24569d39e31519b.gifЕсли интересно, прошу под кат! (много картинок!)Проект некоммерческий, без пурчейзов, рекламы и смс, да и на текущей стадии напоминает скорее концепт. Возможно, читателям хабра знакома вторая картинка — одним прекрасным днем я увидел ее в этом посте, да-да, восторженные комментарии мои. Сначала немного слов про графику.

Графика.Я, к счастью или к сожалению, обычный программист и рисую довольно жалко, поэтому пришлось искать художника. А какой бюджет может предложить женатый мужчина для своей развлекалочки? Ну, оказалось в итоге около $1000, но конечно же этого не хватило бы на профессионального гейм-художника, поэтому спустя какое-то время вышел на девочку, которая весьма неплохо рисует в акварели, но фотошоп не видела в глаза. Начали с фона и, так как я всегда хотел сделать хоррор, жутких деревьев. Сканы вышли такими (картинки кликабельны): 8f1862bc8de8422d87885cf65fa24c51.jpge9a6ebbdc212424e8c776aabb95602d6.jpg7ccbc1b2960246a2950ee9560e459154.pngПоследний скан — платформа — так вообще напомнила мне чем-то первый StarCraft по цветовой схеме. И так мне эта акварель понравилась, что я решил не переводить её в вектор и оставить как есть, вырезав и маленько подретушировав в фотошопе. В итоге из множества эскизов в игре появилось 13 видов деревьев, 2 вариации платформ и 5 персонажей, за которых предлагается одновременно играть игроку. В бумаге это выглядит так: cf6b6112ee9541b3a80ce8385536c69e.jpgC персонажами получилось сложнее. Из многих-многих вариантов деток мы выбирали очень долго. Первоначально я даже не знал, сколько их будет — с клавишами получалось естественней, но на экране айфона места не так много, как на midi-клавиатуре. После долгих экспериментов их осталось 5. Весь список еле уместился на фотографию: 42628ab3a2434e9e986e2698b6c5c243.jpgПосле сведения всего скриншот с победителями выглядит так: 5d3abef8fa8030074e460b9ae5b457c8.jpgВсем персонажам дали клички, к примеру самый тощий — Освенцим. Кое-кого назвали в честь внешнего сходства с коллегами. С анимацией было сложно, освенцима пришлось даже переделать (в текущей версии он дергается, как паралитик, в версии 1.1 вылью обновленного). Сводил все по слоям в фотошопе, проверял анимированным гифом. На сведение и вырезку одного персонажа уходило примерно 3 часа: bb71186cee1e4701b428a0b7317ad9bd.pngЗато результатом я весьма доволен. Конечно, современные дизайнеры и аниматоры ставили в упрек маленький FPS анимации — она состоит из восьми кадров для каждого игрока — зато картинки получились уж очень похожими на мультфильмы 20–30х годов прошлого века: dc054369ef6c425da4704d37bbcc82b1.gifМне сразу стало интересно — все эти точки, штришки, потертости, появляющиеся на кадрах, в старых мультиках появились по причине старения пленки, либо же как у нас — от случайных движений карандаша по бумаге? У них ведь не было понятия пост-продакшена, картинки скорее всего отснимались и клеились как есть. Если у кого есть информация или соображения, поделитесь пожалуйста в комментариях.Программинг. Изначально я разработал полностью работающий прототип на Cocos2D+Box2D, но мне не понравились несколько нюансов:

С точки зрения Box2D, каждый игрок представляет собой параллелепипед. Если бы бежал один игрок, некоторые огрехи и погрешности просчета физики были бы просто незаметны, а при синхронном беге пяти игроков в произвольные участки времени дистанция между ними то сокращалась на пару пикселей, то наоборот увеличивалась. С чем это было связано, я так и не разобрался, но нашел в интернете информацию, что такие сложные движки не стоит использовать в раннерах хотя бы по этой причине — выходит, не я один наткнулся на эти грабли; Мне не особо понравился Cocos2D ввиду его слабой инкапсуляции — в SpriteKit код получается короче и более понятным, ввиду отсутствия ОГРОМНОГО_ВИДА_OPENGLES3_КОНСТАНТ и иных прямых вызовов OpenGL, которые мне порой напоминали кошмар WinAPI — нужно либо знать его досконально, либо курить кучу документации и форумов, что в конечном итоге приведет к доскональному знанию огромного количества констант, без которого мне неплохо живется. В итоге я переписал все на SpriteKit (а что, имею право, проект-то мой), а в качестве физики написал примитивный движок — не более, чем требуется для 2D-раннера, строк на 100. Ничего интересного или нового в нем нет, любой программист напишет такой же за день. Зато единицы измерения из сферических в вакууме превратились в пиксели на секунду и на секунду в квадрате — с такими вполне приятно работать, в отличие от абстрактных для девайса метрах :)

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

Также я довольно хитро сделал параллакс деревьев — когда крутишь телефон в руках, они изображают 3D-эффект. Добавил невидимую вьюшку, параллакс которой обсчитывает сама iOS, и на каждый тик игры считываю дельту ее координаты, которую умножаю на удаленность дерева от пользователя (1 — самое дальнее, 0 — самое ближнее) и складываю с (X; Y) самого дерева. Получается довольно симпатично и производительно.

Кстати, с производительностью тоже пришлось изрядно повозиться, но тут больше по неопытности — к примеру, самым большим тормозом оказалось то, что я обращался к UIKit-элементу на каждом цикле перерисовки. Наконец-то я понял, для чего в игровых движках есть свои кнопки и лэйблочки! А я-то, неуч, сделал HUD на обычных iOS-овых контролах.

Заключение. Музыку мне по знакомству написал лидер одного белорусского рэп-коллектива за символическую плату в 1 банку бабушкиной аджики, которую он любит со времен обучения в институте. По-моему, она прекрасна сама по себе (и музыка, и аджика). Остальные звуки нашел наш тестировщик Игорь на стоках, за что ему огромное спасибо как и всем, кто помогал мне в создании игрушки. Чуть не забыл, ссылка на апстор, приятной игры! Буду рад каждому комментарию!

© Habrahabr.ru