Об идее
Самая интересная часть истории заключается в том, что первоначальная идея абсолютно не совпала с итоговой реализацией. Почему? Да все просто. Сначала у меня была идея создания головоломки с использованием машины Тьюринга.
Чтобы было понятнее, напишу пример. Представим, что у нас есть немного всех поднадоевшие Angry birds. Механика игры проста, мы берем птицу, нацеливаем ее на свинью и запускаем. А теперь приделаем сюда машину Тьюринга. К примеру, внизу экрана есть меню, отражающее порядок действий. Мы не просто запускаем птицу, а пишем в очередь действий, с какой скоростью и под каким углом ее запускаем. При этом уровень будет пройден, когда все действия будут выполнены правильно.
Разумеется, в моем проекте не было злых птичек, смысл был в том, чтобы поджечь ящики в правильном порядке, но сейчас нет никакой разницы. В итоге я решил, что проект слишком сложный как для игры, так и для реализации. Я к тому времени работал с движком всего месяц и умудрился сделать огонь, который распространялся именно по конкретным ящикам, а вот с самой машиной Тьюринга у меня были проблемы.
После этого, в один прекрасный момент я переиграл в fruit slice, после чего зашел в unity и сделал так, чтобы имеющиеся у меня ящики просто вылетали со всех сторон. В общем, минут 10 я наблюдал за этой картинкой…
Так и сформировалась конечная идея.
Однако мы все знаем, что написать чистый клон игры не достаточно, чтобы суметь ее продвинуть. Идея добавить в игру фрукты была выслана срочным рейсом со всеми своими чемоданами сразу, как только она появилась. Идея разрезать ящики пополам была отправлена туда-же. Мне нужны были взрывы! Яркие картинки должны привлекать пользователей. Но идея просто взрывать ящики и получать за это очки считалась минимум недоделанной до своего идеала. Чтобы в игру было действительно интересно играть, после взрыва ящика должно что-то происходить. Кроме того, было бы интересно, если бы время от времени действовали какие-то события, дул ветер или исчезала гравитация.
Со всеми этими мыслями я решил, что пришло время взять в свои руки тетрадь и попробовать зарисовать концепт игры.
Теперь самое время рассмотреть варианты реализации всего того, что я написал выше.
Об игре
Самый первый разработанный концепт выглядел так:
Просто вылетающие ящики, которые можно было взорвать, нет ничего проще! Однако останавливаться на этом было бы глупо!
Следующая версия игры выглядела вот так:
Ящики стали разноцветными. Это уже было интереснее. Более того, разноцветными они стали не просто так, по цвету определялся тот эффект, который происходил после взрыва конкретного ящика.
Например, после взрыва желтого ящика появлялась неподвижная сфера (ее видно на скрине сверху). При разбивании об нее других объектов игрок получал бонус. После взрыва синего ящика тоже появлялась сфера, но теперь самонаводящаяся, если она во что-то попадает, игрок получает штраф (итоговое количество выигранных очков уменьшалось).
Добавление таких фишек сделало игру более интересной, что лучше всего, пользователь переставал разбивать ящики бездумно и у него возникал выбор, какой из ящиков лучше разбить первым.
Так я стал постепенно развивать сформировавшуюся идею. Позже появились события, которые происходили в зависимости от времени. Например, начинал дуть ветер и сдувал все ящики или начинал дуть холодный ветер, который тоже сдувал все ящики, плюс еще и замораживал их, из-за чего текстура менялась на корку льда, и сложнее было идентифицировать, какой ящик сейчас летит.
Дерево умений.
Позднее было добавлено дерево умений. Вот скрин:
Скрин дерева умений взял в одной из последних сборок игры, раньше оно выглядело по-другому.
По моему скромному мнению – игры с деревом умений живут дольше игр без него.
В общем, игровой процесс получился довольно оригинальный. В названии игры оказалось все проще. Например: есть игра fruit slice. Что там нужно делать? Резать фрукты, конечно! Есть моя игра, в которой нужно взрывать все, что есть на экране. отсюда и название — Explode It!
С идеей закончили, приступим к интересным моментам, которые возникли по мере реализации.
Техническая часть проекта
Прежде чем приступить к описанию технических моментов скажу, что это моя первая игра, в ней много косяков, так что конструктивная критика, сами понимаете, приветствуется.
Игра создавалась на Unity. На мой взгляд – этот выбор один из лучших, если не просто лучший. У движка есть огромное количество плюсов. Он прост в освоении, он кроссплатформенный, у движка есть огромная работающая экосистема, которая включает в себя форум, assetstore и много чего другого.
Ну и самое главное – он бесплатный. Сейчас, насколько я знаю, существуют такие вещи, как unreal engine 4 и source 2, которые тоже сделали бесплатными, но когда я начинал знакомство с темой, эти движки еще не были выпущены, так что выбор был очевиден.
UI
Вот не нравится мне стандартный UI в Unity. Медленный, возможностей мало, привязки к сторонам экрана нет (сейчас, насколько я знаю, есть). Основная его проблема – финкция OnGUI, которая может срабатывать несколько раз за кадр, что для мобильных устройств неприемлемо.
Здесь есть один момент, я писал свой проект на unity версии 4.5.4, в этой версии не было интерфейса с привязкой к различным сторонам экрана (а при переходе на новую версию происходили сумасшедшие баги, она была на стадии бета тестирования), так что, не долго думая, я стал искать замену стандартному UI. Так я нашел NGUI.
NGUI
Принцип работы NGUI следующий: все GUI-элементы являются простыми объектами, имеющими свой материал и без проблем отрисовываются даже мобильниками без ущерба производительности. Здесь возникает один момент: Приходится выводить отдельные функции для обработки событий, таких как нажатие на кнопку и ей подобные.
NGUI платный. При покупке в assetstore последняя версия стоит 95$ и требует наличие Unity версии 4.5.5 и выше. Однако, кто ищет, тот всегда найдет. NGUI распространяется бесплатно, более того, он распространяется бесплатно на официальном сайте, ссылка вот: www.tasharen.com/forum/index.php?topic=526.0 Также его можно найти на официальном форуме Unity: forum.unity3d.com/threads/ngui-free-edition.124032
В конце поста написана одна важная деталь: «В чем подвох? NGUI 2 устарел в сентябре 2013 в момент выхода NGUI 3. Это прошлая версия, в которой нет новейших особенностей, присутствующих в третьей версии. Более того, в ней отсутствует саппорт. Есть еще одно ограничение, которое накладывается на коммерческое использование этой версии. Она попадает под условия коммерческого использования Unity Free. Free версия Unity не может быть лицензирована для коммерческого использования в том случае, если общий доход вашей организации не превышает 100000 долларов США (по итогам предыдущего финансового года)».
Английский оригинал читайте под спойлером:
Ссылка на FAQ (LICENSING & ACTIVATION) Unity: unity3d.com/unity/faq
В общем, я пока могу пользоваться этой версией.
Основной плюс этой UI системы в том, что мы можем осуществлять привязку к разным сторонам экрана, что позволяет создавать функциональные интерфейсы. Более того, все объекты интерфейса содержаться в одном атласе. Атлас – это такая громадная текстура, которая содержит в себе все элементы интерфейса. Например, текстуру шрифта, кнопок, иконок и всего прочего. На мобильных устройствах желательно ограничивать размер такой текстуры до 2048/2048 с целью оптимизации.
Вообще, я сейчас не буду описывать все особенности NGUI, на хабре есть замечательная статья (специально для начинающих), в которой уже описана часть его особенностей, ссылка: habrahabr.ru/post/211536
Пример интерфейса, написанного на NGUI:
Update vs coroutines
Еще один вопрос, возникший по мере разработки проекта, как можно эффективно рассчитывать время. Раньше я это дела в функции Update, но тут есть одна проблема. Эта функция срабатывает каждый фрейм. Если в игре 60 fps, она сработает 60 раз в секунду. Для телефонов наличие нескольких таких функций на сцене будет убийственным ударом по производительности. Желательно сокращать количество вызова этой функции, или заменять функцию другим вариантом.
Хороший пример решения такой задачи – сопрограммы.
Например, у нас есть сцена с игровым процессом и нам нужно, чтобы какое-то действие происходило каждую секунду до момента выхода из игры или загрузки новой сцены (таймер, например).
Это можно сделать двумя способами.
С помощью функции Update, мы должны наращивать переменную, подсчитывающую время на величину Time.deltatime.
float currentTimer = 0;
void Update() {
currentTimer += Time.deltaTime;
if (currentTimer >= 1){
//Ваше действие
currentTimer = 0;
}
}
Второй пример. Мы можем сделать по-другому, с помощью сопрограммы и функции WaitForSeconds. Во втором случае нам даже не надо писать условный блок для постоянной проверки текущего времени.
Пример:
IEnumerator Example() {
while(true){
yield return new WaitForSeconds(1);
//Ваше действие
}
}
Разрешение экрана
Ни для кого не секрет, что Android – тот еще зоопарк устройств. Отсюда вытекает множество моментов веселых и не очень. Один из таких моментов – разрешение экрана.
Если с IOs тут все более-менее понятно, то с Android возникают вопросы.
Изначально вся визуальная часть игры подстраивалась под разрешение 16:10.
Насчет имеющихся разрешений вообще: здесь можно посмотреть примерную(!) таблицу использующихся разрешений экранов на платформе Android: geektimes.ru/post/169141
Вот таблица разрешений экрана для планшетов:
Также таблица с разрешениями экранов для телефонов:
После всех тестов единственной проблемой оставалась подладка под разрешение 4:3.
Была пара способов исправить всю ситуацию:
- Оставить картинку такой, какой она является для всех соотношений экрана. В коде картинки не менять, просто подладить в редакторе. Нормальное решение, если нет времени делать отдельную сборку под каждое соотношение и писать кучу скриптов, в которых придется менять изначальный размер картинок.
Плюсы метода: не надо писать никаких скриптов и делать несколько сборок под различные соотношения. Чистая экономия времени.
Здесь есть один минус. Предположим, что мы сделали так, что вся картинка помещается на экран при соотношении 4:3 (обычно именно на экранах с этим соотношением в landscape ориентации картинка вылезает за края экрана), однако будем считать, что нам удалось. При этом игра на соотношении сторон 16:10 будет выглядеть еще нормально, на 16:9 будут ярко выражены неиспользуемые области по бокам. - Менять размер картинок в зависимости от соотношения. Я так делал в сцене, отвечающей за дерево умений. Но вообще, если у вас дефицит времени – способ может показаться не самым лучшим. Слишком много всего приходится менять. Не только отдельные текстуры, но еще и сам текст (который тоже вылезал за экран) и много чего другого.
- Менять размер камеры. Способ человека, который явно нацелился поймать халяву. Он почти никогда не помогает, потому, что меняется не только ширина камеры (меня интересовали неиспользуемые области справа), но и высота камеры, что логично. Также это не поможет, если вы используете NGUI, и у вас на сцене есть скрипт IUDraggablePanel, которые отвечает за прокручиваемое меню.
В общем сразу скажу, что я использовал первый вариант, получился примерно вот такой результат.
4:3
3:2
5:3
16:9
16:10
Как видно из картинок выше, при разрешении 4:3 меню занимает почти весь экран, а вот при разрешении, например, 16:9 становятся видны неиспользуемые области по бокам.
В дереве умений не плохо помог второй вариант, первоначально прокручиваемое меню заезжало под кнопки, позже стал редактировать его в момент загрузки уровня.
Тем не менее, считаю, что с проблемой на своем уровне справился.
Тестировщики
Они нужны… более того, они нужны просто ОБЯЗАТЕЛЬНО. Насчет многих проблем, о которых программист даже примерно не подозревает, ему сообщают тестировщики.
Например, я первоначально не знал, что игра, оказывается, сложная, анимации слишком долгие, вот та кнопка срабатывает несколько раз, пока на ней просто держишь палец, умения при определенных условиях не срабатывают и так далее.
Короче, приведу пару примеров, как изменилась игра после ее тестирования.
Дизайн дерева умений поменялся чуть-ли не полностью (под катом). Кстати говоря, в игре полностью изменился шрифт.
Старый вариант:
Новый вариант:
Однотипные разноцветные ящики поменялись на различные геометрические объекты. Кстати здесь интересный момент, человек лучше понимает ситуацию, когда кроме цвета в объектах меняется что-то еще, например, геометрическая форма. Это оказалось интересно, т.к. мне изначально было достаточно чисто цвета.
Старый вариант:
Новый вариант:
На этом с интересными техническими моментами все. Еще, конечно, можно написать про процесс оптимизации, но про процесс оптимизации я буду писать очень долго, эта статься станет просто громадной. Если у вас, господа, возникнет желание почитать, я напишу статью на эту тему позже.
Если все пойдет так, как я запланировал, позже поделюсь информацией о продвижении проекта и расскажу про особенности публикации и аналитики, думаю, это многим будет интересно.
На этом все, всем спасибо за прочтение статьи.
Комментарии (14)
Igor_Sib
17.06.2015 07:59+3Update vs coroutines
…
Это можно сделать двумя способами.
Можно еще через Invoke();
void Test() {
Debug.Log(«Test»);
}
Invoke(«Test», 1f);
запустится через секунду.ConceptCoder Автор
17.06.2015 17:02Тоже хороший вариант. Я его нашел, когда уже почти весь код игры был наполнен сопрограммами, поэтому не стал использовать этот метод.
spice_harj
17.06.2015 10:04-6Вообщем не понятно, к чему был именно Unity3D, когда игра полностью 2D.
А по-существу — так держать!Alexsey
17.06.2015 14:30Как это не странно, но именно для игр с 2D перспективой юнити чаще всего и используют. Не в последнюю очередь из-за низкого порога вхождения и элементарнейшей сборки билда игры для любой из поддерживаемых платформ.
ConceptCoder Автор
17.06.2015 17:07Главное преимущество в том, что Unity кроссплатформенный. Есть еще один момент. Я не до конца в курсе, как функционируют 2d движки типа Cocos 2D, но насколько я знаю, чтобы сделать вращающиеся объекты, мне нужно было-бы делать что-то типа анимации спрайтов. Художник из меня так себе, да и 3D с этой задачей справляется лучше
spice_harj
17.06.2015 17:20Верно. Если бы Вы не прибегали к этому ленивому юнити, Вы бы поработали с шейдерами, написали бы много развивающего кода для 2д, возможно изучили бы атласы и работу со спрайтами — что очень даже легко.
А все, что Вы сделали с юнити (я так понимаю) — это скачали готовые скрипты, нарисовали графику, разобрались с разрешением и покрутили параметры? Я прав?ConceptCoder Автор
17.06.2015 17:39Не совсем. Атласы и работу со спрайтами я изучил, т.к. пришлось работать с NGUI, а он работает с помощью атласов, готовые скрипты я тоже не качал, код мой.
А вот с анимацией спрайтов я работал только на уровне интерфейса, а не на уровне игровых объектов, вот тут Вы угадали.spice_harj
17.06.2015 17:48+1В любом случае чем глубже копнёте — тем лучше. Лучше меньше но лучше, чем больше, но дерьма, которого на сторах пруд пруди (просто слова не относящиеся к Вашему проекту).
whunter
17.06.2015 13:13Буду ждать от вас новых статей, интересно. Скажите, а сколько времени вы потратили на разработку в том виде, в котором игра сейчас?
ConceptCoder Автор
17.06.2015 17:08Скажу так, универ и моя собственная лень сыграли в этом свою роль. Ушло около 8 месяцев.
niq
17.06.2015 17:33Кроме тестировщиков еще и дизайнеры очень нужны. Визуальный интерфейс от разработчика всегда максимум на троечку получается.
ConceptCoder Автор
17.06.2015 17:42Вот это точно, но нету у меня знакомых дизайнеров.
Я слышал, что если работать с издателем, они могут помочь с графикой (если правильно выбрать издателя). Не в курсе, есть такой момент?
Pashkevich
Хорошая статья, ждем продолжения про публикацию и доход.
ConceptCoder Автор
Напишу, но позже.
Тут дело в том, что я
хорошо продумал ситуациюи выпустил игру во время подготовки к диплому. В итоге пока нет времени на ее поддержку.Хотя, в итоги получился своеобразный незапланированный soft launch. С таким результатом можно написать издателю.