Про что? О чем делать игру? Вот какие вопросы я задавал себе в течение нескольких дней. Но позже мне пришёл на ум очень интересный и захватывающий момент в игре Valiant Hearts. В одной сцене данной игры главный герой (солдат) бежал под градом бомб и в определенный момент ему нужно было остановиться, чтобы не попасть под взрыв снарядов.
И вот я придумал геймплей и концепцию для игры, а название простое — Crazy Crazy. Теперь надо было начать создание этого шедевра.
Графика
Я долго не мог выбрать нужный графический стиль для своей игры. Бегал от одного к другому. Но в конце концов понял, что этот стиль обязан быть простым в рисование (чтобы не тратить много времени на создание текстур) и особенным. Я всегда любил некий контраст черного, белого и красного, что идеально подходило для моей игры, поэтому выбор пал на стиль с данными оттенками.
Поначалу я пытался максимально наполнить деталями своего главного персонажа, чтобы его запомнили, но посмотрев на героев других раннеров, был сделан выбор упростить его. И по-моему, получилось только лучше.
Анимация была сделана старым добрым способом, т.е. она была покадровой. Другую я не умею делать, поэтому и выбирать мне особо не приходилось. В игре всего лишь несколько анимаций: бег героя, остановка героя, появление тени от бомбы, взрыв бомбы. Так что на её создание я потратил не так много времени.
А вот с созданием бомбы получилось немного интереснее: сначала я нарисовал фашистский знак в середине её текстуры для того, чтобы там не было пустоты. Но забегая вперёд я вам скажу, что это было не самое лучшее решение. При выставление возрастных ограничений, как в App Store, так и Google Play, учитывается данный пункт, так как эта символика является знаком экстремизма во многих странах.
Техническая часть
Вот я и приступил к написанию программной части для своей игры.
Попытка №1:
Я, как наивный маленький мальчик, решил, что смогу написать игру с нуля с использованием OpenGl, с которым у меня уже был ранее опыт (писал небольшие игры типа змейки). Но спустя уже 2 недели программирования под Android я осознал минусы своего выбора:
1. Нужно было написать много кода с чистого листа, на что ушло бы немало времени.
2. Мне бы пришлось программировать игру заново под ios, где нужно еще знать Swift/Objective-C. На это бы ушло еще огромное количество времени.
Поэтому я понял, что данная схема не позволит закончить игру к началу лета, из-за этого мне пришлось сменить тактику.
Попытка №2:
Теперь я наконец осознал, что для быстрого создания игры под Android и iOS мне нужен был кроссплатформенный бесплатный фреймворк с небольшим количеством функций. И вот мой выбор пал на LibGDX. В нем есть простая и понятная документация и он работает как на Android, так и на iOS. Вскоре я набрел на великолепную статью на Хабре "[LibGDX] Создаем клон Flappy Bird — Zombie Bird". С помощью неё (спасибо переводчику статьи eliotik) я смог за 10 дней создать некий прототип своей игры с текстурами и основным геймплеем. Никакого меню, вывода GameOver и музыки там не было. Но мне уже понравилась моя игра. Простая в управлении, но и немного хардкордная в геймплее.
Попытка №3:
Вроде бы мне все понравилось в игре и коде, но благодаря комментарию от 1nt3g3r в той статье я понял, что многое сделал неправильно и некрасиво. Не было начального экрана, во время которого в другом потоке загружались текстуры, была просто ужасная архитектура игры и еще множество мелких проблем. Я себе такого не мог позволить, поэтому пришлось переписывать игру, основываясь уже на западных статьях о libGDX.
Но в конце разработки у меня возникли две главные проблемы:
Поддержка различных разрешений экрана.
Глупый респаун бомб на карте.
Поддержка разных экранов
Как вы знаете, на Android есть такая ужасная и в тоже время прекрасная вещь, как фрагментация. Поначалу я создавал игру только под свой планшет (Nexus 7 2013), хотя знал, что мне придется рано или поздно добавлять поддержку других экранов в игре. Я думал так решить данную проблему: просто умножать на определенное коэффициент ширину и высоту текстур, но, к сожалению, это не помогло. На планшете с маленьким разрешением отображалось хорошо, а вот на старом телефоне с экраном из 90-х не очень. Поэтому я разделил виртуальный мир игры на 2 основных экрана (или viewport), которые поддерживаются в libGDX:
StretchViewport — экран, который растягивается на всю ширину и длину реального экрана, при этом не сохраняя пропорций. На нем я расположил background-текстуру игры. Т.е. хоть на iPad, хоть на моем Nexus были видны во весь экран обои.
FillViewport — экран, который растягивается до определенных размеров в соответствие со своими пропорциями. В данном случаи я сделал виртуальный экран размером 800/450, т.е. соотношения сторон равно 16 к 9. На нем я расположил все оставшиеся объекты игрового мира. Из-за своих особенных характеристик он не занимает полностью экран на некоторых устройств (к примеру на Айпаде), из-за чего появляется такая нелепость, как вылетание бомб из невидимой границы этого экрана (см. рисунок). Но зато геймплей на всех девайсах одинаковый и бомбы летят на айфоне столько же времени, сколько и на nexus 7.
Респаун Бомб
С появлением бомб все не так однозначно. Что вообще там с бомбами? Да все просто: сначала появляется тень, она увеличивается и темнеет, в это же время падает с неба бомба, а когда она сталкивается с землей, образуется взрыв и тень исчезает. Именно взрыв и убивает персонажа.
Я несколько раз перерабатывал алгоритм появления бомб, но так и не пришел к совершенству. Сейчас я тебе все объясню.
Начнем с того, как он собственно работает:
1. Находим рандомные X координаты новой тени от бомбы в диапозоне виртуальной ширины экрана (800 пикселей) + 400 пикселей.
2. Проверяем координаты новой тени от бомбы на то, чтобы она находилась на ранее заданном минимальном расстояние от других теней (именно теней, а не взрывов бомб).
3. Если все хорошо с проверкой, то появляется новая тень от бомбы, а после и взрыв.
Вот собственно код (простите меня, он ужасен):
private boolean checkCollision(float bombx, float minderuction){
boolean good=true;
for(short i=0; i<bombs.size(); i++){
if(!bombs.get(i).getRocket().isHaveDamage()){
float curbombx = bombs.get(i).getShadow().getX();
int curbombwidth = (int)(bombs.get(i).getShadow().getWidth());
if(curbombx>bombx){
if(bombx+curbombwidth+minderuction >= curbombx){
good = false;
break;
}
}
else
if(curbombx+curbombwidth+minderuction >= bombx){
good = false;
break;
}
}
}
return good;
}
public boolean Generate(float minderuction, float minx){
boolean createbomb = false;
if(getRandomInt(2)==0)
if(bombs.size()<16){
float newbombx = getRandomFloat((float)(screenWidth+400));
if(newbombx > minx && checkCollision(newbombx, minderuction)){
CreateBomb(newbombx);
createbomb = true;
}
}
return createbomb;
}
Что же не так? Данный алгоритм основан на неуправляемом рандоме. Игрок может скучать 5 минут из-за того, что бомбы не мешают ему пробегать игровое поле, а потом умереть мигом из-за двух близкостаящих бомб. По идеи можно увеличить минимальное расстояние между бомбами, но вот не все так просто. Это расстояние было просчитано на основе длины тормозного пути главного героя, а так же его ширины. И из-за его увеличения игра может стать слишком легкой -> неинтересной.
Выпуск игры
Итак, разработка игры заняла у меня примерно 2 месяца (почти в пару недель уложился). Теперь настало время выкладывать игру в Google Play. Здесь все очень просто: зарегистрировался разработчиком на сайте Google, заполнил все поля в консоли, выложил скриншоты. Хотя меня удивило то, что из-за новой системы возрастных ограничений рейтинг моей игры в США поднялся до 12+, но мне тут уже ничего не сделать. После отправил приложение на обработку и перешел к выпуску игры в App Store.
Как вы знаете, для разработки под iOS нужен Mac. А у меня его не было (да и сейчас нет). Поэтому мне пришлось выкручиваться. Я узнал, что можно запустить пиратскую версию OS X на виртуальной машине в Windows. Этим я занимался примерно неделю. Смог установить нужную версию данной ОС только с 7 раза. Программы на ней жутко тормозили, только XCode скачивался и устанавливался порядка 8 часов. Но позже, настроив виртуальную машину, я смог выжать из неё не тормозящую картинку (и то игра с фреймворком компилировалась примерно полтора часа).
Теперь надо было подключить Game Center и рекламу AdMob к iOS-проекту. Это не составило особого труда, так как у меня уже был опыт работы с Android приложением.
С отладкой у меня возникли некоторые проблемы. Оказалось, что для тестирования своей игры на iPad (который мне друг одолжил для разработки) нужно иметь статус разработчика. Я зашел на сайт Apple, оставил нужную заявку, отправил данные своей карты и примерно через 2 дня у меня компания сняла деньги с неё, а ключ, который они прислали для активации аккаунта разработчика, был нерабочим. По этому вопросу я им писал примерно 5 раз в течение 2-х дней, ожидая ответа. Только на 3-й дней, когда я уже собирался окончательно заспамить их поддержку, они отослали мне рабочий ключ активации от аккаунта разработчика. Сама поддержка ответила только на четвертый день, но это уже не важно. (Сейчас я подумываю о том, что не надо было писать им столько обращений в поддержку.)
Игра была готова под iOS и теперь мне нужно было её выпустить. Скриншоты под разные диагонали устройств для App Store я сделал с помощью фотошопа, описание для игры мне помог перевести на английский мой друг. Наконец игра была отправлена. Сначала попросил ускоренной проверки приложения от Apple, но они ответили, что и так очень заняты, и мне пришлось ждать модерации игры 8 дней.
Вот, собственно, и вышла моя первая игра под Android и iOS. Я этому очень рад и надеюсь, что вам понравилась моя история разработки под эти две великолепные ОС. Если интересно будет что-то еще узнать, я с удовольствием отвечу на все ваши вопросы, а может быть, и новый пост напишу.
Благодарю Tibr за помощь в написании статьи.
Комментарии (43)
myrrec
16.06.2015 19:34-8«В написании статьи помогал», по-моему, немного неграмотно. Лучше заменить на «С написанием статьи помогал», а лучше, «Благодарю $username за помощь в написании статьи».
Mishok2000 Автор
16.06.2015 19:38Спасибо. Исправил
myrrec
16.06.2015 19:48-5Если уж решили исправлять, вот ещё несколько ошибок, на которые в первую очередь натыкается глаз:
- «Данный алгоритм в любом случаи»
- «в нашем случаи на iPad»
- «просто умножать на определенное коэффициент (ширина экрана\ширина экрана моего нексуса) размеры текстур»
- «где нужно еще знать Swift/C-Object» — не уверен, но там же Objective-C? Если не прав, скажите
- «Но с забегом наперед я вам скажу» — лучше сказать «забегая вперёд».
- Абзац «Респаун бомб» я бы вообще переработал — почти в каждом предложении есть слово «бомба», но это не очень существенная претензия
- «Я этому очень рад и надеюсь вам понравилась моя история разработки под эти две великолепные ОС» — вы не проверяли запятые? Их там попросту нет
И это я ещё не всё посмотрел…Mishok2000 Автор
16.06.2015 19:58Исправил, все кроме абзаца про респаун бомб.
Запятые проверял, но про последний абзац забыл.
С Objective-C я как-то вообще лоханулся.myrrec
16.06.2015 20:04-5Исправьте тогда ещё хотя бы «Неконец игра была отправлена», а то читать больно. И «фотошоп» не умеет делать снимки экранов(во всяком случае, Adobe Photoshop CC 2015.2 9.0, который стоит у меня)
Mishok2000 Автор
16.06.2015 20:14+1Первое исправил. По второму: я конечно мог написать так: <Зануда> Для создания скриншотов я нажимал на кнопку PrtScn, которая располагается в правом верхнем углу клавиатуры, позже создавал новый проект в Photoshop, копировал туда с помощью «горячих» клавиш screenshot, а уже после пользовался функционалом этой чудесной программы, т.е. изменял размеры изображения до нужных мне величин. </Зануда>, но я думаю и так все понятно :)
Но все равно спасибоmyrrec
16.06.2015 20:24-6Всегда пожалуйста. Имхо, если бы этих ошибок не было с самого начала, возможно, рейтинг был бы выше
Defuera
16.06.2015 22:40Дайте пожалуйста ссылочку, а то по названию Crazy Crazy в Play Store ничего не нашел -(
Mishok2000 Автор
16.06.2015 22:46Если меня не забанят за рекламу, то прошу:
Google Play: play.google.com/store/apps/details?id=com.prosto.crazycrazy.android
App Store: itunes.apple.com/app/id995651270
Strizh0
16.06.2015 23:49Всегда приятно сделать что нибудь самому, хоть и криво. Жаль только что в наше время этим не кого не удивишь. За статью спасибо, прочитал с удовольствием. Только зачем рекламу вставили если делал для себя?
Mishok2000 Автор
16.06.2015 23:55В первую очередь — ради опыта. А так же думал, что маленько, но смогу заработать с помощью игры.
PapaBubaDiop
17.06.2015 00:04Скриншоты делаются в эмуляторе Xcode нажатием cmd+S. Скрипач для этого не нужен. 30-секундное видео делается при помощи QTime и реального устройства.
Mishok2000 Автор
17.06.2015 00:10Честно говоря, я бы с удовольствием запустил эмулятор iOS, если бы ресурсы виртуальной машины с OS X позволяли бы мне это сделать.
Про видео не знал, спасибо большое!
Denai
17.06.2015 03:29Посмотрел на android-версию, увидел «Размер 15M». Что заставляет игру столько весить?
Mishok2000 Автор
17.06.2015 11:29Я думаю, что просто libGDX немало весит + я где-то по-серьёзному скривил.
Сейчас находиться в разработке вторая игра(летом просто делать нечего), и в ней я попытаюсь разобраться, почему приложение так много весит, а так же попробую решить данную проблему. Может на хабре позже отпишусь об этом.Grammidin
17.06.2015 11:47А сколько «весят» графические ресурсы? Может, в них дело.
Mishok2000 Автор
17.06.2015 12:16Примерно 8 метров.
Denai
17.06.2015 14:45Для того что фигурирует на скриншотах как-то многовато, вам не кажется?
Mishok2000 Автор
17.06.2015 15:09Согласен, многовато. Я, к примеру, мог background сохранить ни как png, а как jpeg для экономии места, так же в игре есть 3 текстуры руки с большим пальцем с разными углами поворота, хотя можно было бы использовать всего одну текстуру и программно переворачивать её. Таких моментов еще не мало, но мне честно говоря лень над этим работать уже, да и цели я себе такой не ставил.
Denai
17.06.2015 15:20Для мобильного интернета каждый мегабайт может означать минуту времени загрузки, а то и больше
DevAndrew
17.06.2015 23:37Я скачал версию iOS. Она вообще получилась 41.2 MB. Для игры подобной на Flappy Bird но без графики, это просто чересчур.
Mishok2000 Автор
18.06.2015 00:45Я посмотрю, что с этим можно сделать. Как я понимаю, такой большой объем файла из-за RoboVM.
grcool
18.06.2015 16:22А я еще считал Corona SDK прожорливой)
На Короне, кстати, за пару часов такую игру можно написать)Mishok2000 Автор
18.06.2015 16:50Поверь, и на LibGDX я сейчас за пару часов смогу такую игру написать. Я пару месяц писал из-за того, что создавал игру после школы, когда время было. Т.е. бывало час, два поработаю, бывало вообще нет времени. Переписывал игру не раз.
grcool
18.06.2015 16:57Верю) Просто не вижу смысла писать приличный объем кода, если размер приложения будет настолько большим)
Есть множество SDK на Lua, в которых все делается в разы проще и быстрее — за это платишь размером пакета. А тут выходит — не быстро, не просто и размер пакета огромный)
roces
17.06.2015 19:18Судя по статистике игра будет пользоваться популярностью на Android. Поздравляю и надеюсь она принесет вам приличный доход.
На мой взгляд вы сделали очень правильный выбор в плане временем разработки, интересности игровой механики и монетизации.
Если будете делать хотя бы одну такую игру в месяц, думаю, что скоро это может стать вашим основным источником дохода. Главное не замахиваться на реально большие проекты пока что.Mishok2000 Автор
17.06.2015 19:51Ну я думаю, что данная игра уже особых денег не принесёт, хотя кто знает…
Новый проект у меня на планку выше Crazy Crazy, но все же не огромный.
Спасибо за напутствие.
Redgard
18.06.2015 12:48Желаю успехов в развитии но зачем гнаться за кросс платформенностью? Тем более даже если у вас нет Mac на вашем месте я бы делал приложения эксклюзивно под Android. И на размер файла это скажется с пользой. Сам я делаю свои приложения только под iOS и всегда стараюсь пользоваться уникальными преимуществами выбранной платформы.
Goodkat
18.06.2015 14:42Так как игра написана на LibGDX, то должно быть довольно просто переделать её под OS X и Windows, только добавить управление мышкой и клавиатурой и можно будет выпустить в Mac App Store и Windows Store.
AMDev
07.07.2015 01:06Приятно видеть, как человек, не имея мака и apple девайсов, сумел выпустить игру в app store. Вы просто молодец!
Mishok2000 Автор
07.07.2015 01:24Спасибо. Но apple девайс у меня все же временно был, мне друг Ipad 2 одолжил на 2-3 дня.
DevAndrew
Могли бы вы скинуть ссылки на западные статьи, где приводится хорошая архитектура и т.п.?
Mishok2000 Автор
Для общего понимания Stage и Actor использовал статьи из данного туториала:
www.gamefromscratch.com/post/2013/11/27/LibGDX-Tutorial-9-Scene2D-Part-1.aspx
А так же пользовался официальной документацией о LibGDX
github.com/libgdx/libgdx/wiki