Все началось с того, что я поиграл в сверхпопулярную игру под названием «Flappy bird». Все отлично её знают и описывать игру нет смысла. Но одно сказать я все же должен: Flappy bird зацепила меня своей простотой управления и сложностью геймплея. Я мог играть в нее часами подряд и вдруг подумал — может сделать такую же захватывающую, но при этом простую в управлении и концепции игру? Это же легко, работы на 2 недели, думал я. И так все началось.

Про что? О чем делать игру? Вот какие вопросы я задавал себе в течение нескольких дней. Но позже мне пришёл на ум очень интересный и захватывающий момент в игре Valiant Hearts. В одной сцене данной игры главный герой (солдат) бежал под градом бомб и в определенный момент ему нужно было остановиться, чтобы не попасть под взрыв снарядов.

И вот я придумал геймплей и концепцию для игры, а название простое — Crazy Crazy. Теперь надо было начать создание этого шедевра.

image


Графика


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

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



Анимация была сделана старым добрым способом, т.е. она была покадровой. Другую я не умею делать, поэтому и выбирать мне особо не приходилось. В игре всего лишь несколько анимаций: бег героя, остановка героя, появление тени от бомбы, взрыв бомбы. Так что на её создание я потратил не так много времени.



А вот с созданием бомбы получилось немного интереснее: сначала я нарисовал фашистский знак в середине её текстуры для того, чтобы там не было пустоты. Но забегая вперёд я вам скажу, что это было не самое лучшее решение. При выставление возрастных ограничений, как в App Store, так и Google Play, учитывается данный пункт, так как эта символика является знаком экстремизма во многих странах.



image


Техническая часть


Вот я и приступил к написанию программной части для своей игры.

Попытка №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.

image

Как вы знаете, для разработки под 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)


  1. DevAndrew
    16.06.2015 18:48

    Я себе такого не мог позволить, поэтому пришлось переписывать игру, основываясь уже на западных статьях о libGDX.

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


    1. Mishok2000 Автор
      16.06.2015 19:33

      Для общего понимания Stage и Actor использовал статьи из данного туториала:
      www.gamefromscratch.com/post/2013/11/27/LibGDX-Tutorial-9-Scene2D-Part-1.aspx
      А так же пользовался официальной документацией о LibGDX
      github.com/libgdx/libgdx/wiki


  1. myrrec
    16.06.2015 19:34
    -8

    «В написании статьи помогал», по-моему, немного неграмотно. Лучше заменить на «С написанием статьи помогал», а лучше, «Благодарю $username за помощь в написании статьи».


    1. Mishok2000 Автор
      16.06.2015 19:38

      Спасибо. Исправил


      1. myrrec
        16.06.2015 19:48
        -5

        Если уж решили исправлять, вот ещё несколько ошибок, на которые в первую очередь натыкается глаз:

        1. «Данный алгоритм в любом случаи»
        2. «в нашем случаи на iPad»
        3. «просто умножать на определенное коэффициент (ширина экрана\ширина экрана моего нексуса) размеры текстур»
        4. «где нужно еще знать Swift/C-Object» — не уверен, но там же Objective-C? Если не прав, скажите
        5. «Но с забегом наперед я вам скажу» — лучше сказать «забегая вперёд».
        6. Абзац «Респаун бомб» я бы вообще переработал — почти в каждом предложении есть слово «бомба», но это не очень существенная претензия
        7. «Я этому очень рад и надеюсь вам понравилась моя история разработки под эти две великолепные ОС» — вы не проверяли запятые? Их там попросту нет

        И это я ещё не всё посмотрел…


        1. Mishok2000 Автор
          16.06.2015 19:58

          Исправил, все кроме абзаца про респаун бомб.
          Запятые проверял, но про последний абзац забыл.
          С Objective-C я как-то вообще лоханулся.


          1. myrrec
            16.06.2015 20:04
            -5

            Исправьте тогда ещё хотя бы «Неконец игра была отправлена», а то читать больно. И «фотошоп» не умеет делать снимки экранов(во всяком случае, Adobe Photoshop CC 2015.2 9.0, который стоит у меня)


            1. Mishok2000 Автор
              16.06.2015 20:14
              +1

              Первое исправил. По второму: я конечно мог написать так: <Зануда> Для создания скриншотов я нажимал на кнопку PrtScn, которая располагается в правом верхнем углу клавиатуры, позже создавал новый проект в Photoshop, копировал туда с помощью «горячих» клавиш screenshot, а уже после пользовался функционалом этой чудесной программы, т.е. изменял размеры изображения до нужных мне величин. </Зануда>, но я думаю и так все понятно :)
              Но все равно спасибо


              1. myrrec
                16.06.2015 20:24
                -6

                Всегда пожалуйста. Имхо, если бы этих ошибок не было с самого начала, возможно, рейтинг был бы выше


                1. Mishok2000 Автор
                  16.06.2015 21:17

                  Согласен.


    1. myrrec
      17.06.2015 11:24

      Товарищи минусующие, а есть какая-либо аргументация? То есть теперь даже помочь человеку нельзя?


      1. DevAndrew
        17.06.2015 11:31
        +8

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


        1. myrrec
          17.06.2015 11:34
          -6

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


          1. DevAndrew
            17.06.2015 11:39
            +4

            Как я понял из ваших коментариев вы даже статью не дочитали и уже начали писать по «одной» ошибке.


  1. Defuera
    16.06.2015 22:40

    Дайте пожалуйста ссылочку, а то по названию Crazy Crazy в Play Store ничего не нашел -(


    1. 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


  1. Strizh0
    16.06.2015 23:49

    Всегда приятно сделать что нибудь самому, хоть и криво. Жаль только что в наше время этим не кого не удивишь. За статью спасибо, прочитал с удовольствием. Только зачем рекламу вставили если делал для себя?


    1. Mishok2000 Автор
      16.06.2015 23:55

      В первую очередь — ради опыта. А так же думал, что маленько, но смогу заработать с помощью игры.


  1. PapaBubaDiop
    17.06.2015 00:04

    Скриншоты делаются в эмуляторе Xcode нажатием cmd+S. Скрипач для этого не нужен. 30-секундное видео делается при помощи QTime и реального устройства.


    1. Mishok2000 Автор
      17.06.2015 00:10

      Честно говоря, я бы с удовольствием запустил эмулятор iOS, если бы ресурсы виртуальной машины с OS X позволяли бы мне это сделать.
      Про видео не знал, спасибо большое!


  1. Denai
    17.06.2015 03:29

    Посмотрел на android-версию, увидел «Размер 15M». Что заставляет игру столько весить?


    1. Mishok2000 Автор
      17.06.2015 11:29

      Я думаю, что просто libGDX немало весит + я где-то по-серьёзному скривил.
      Сейчас находиться в разработке вторая игра(летом просто делать нечего), и в ней я попытаюсь разобраться, почему приложение так много весит, а так же попробую решить данную проблему. Может на хабре позже отпишусь об этом.


      1. Grammidin
        17.06.2015 11:47

        А сколько «весят» графические ресурсы? Может, в них дело.


        1. Mishok2000 Автор
          17.06.2015 12:16

          Примерно 8 метров.


          1. Denai
            17.06.2015 14:45

            Для того что фигурирует на скриншотах как-то многовато, вам не кажется?


            1. Mishok2000 Автор
              17.06.2015 15:09

              Согласен, многовато. Я, к примеру, мог background сохранить ни как png, а как jpeg для экономии места, так же в игре есть 3 текстуры руки с большим пальцем с разными углами поворота, хотя можно было бы использовать всего одну текстуру и программно переворачивать её. Таких моментов еще не мало, но мне честно говоря лень над этим работать уже, да и цели я себе такой не ставил.


              1. Denai
                17.06.2015 15:20

                Для мобильного интернета каждый мегабайт может означать минуту времени загрузки, а то и больше


                1. Mishok2000 Автор
                  17.06.2015 15:36

                  Соглашусь с тобой. Я только после релиза понял это.


    1. DevAndrew
      17.06.2015 23:37

      Я скачал версию iOS. Она вообще получилась 41.2 MB. Для игры подобной на Flappy Bird но без графики, это просто чересчур.


      1. Mishok2000 Автор
        18.06.2015 00:45

        Я посмотрю, что с этим можно сделать. Как я понимаю, такой большой объем файла из-за RoboVM.


        1. grcool
          18.06.2015 16:22

          А я еще считал Corona SDK прожорливой)
          На Короне, кстати, за пару часов такую игру можно написать)


          1. Mishok2000 Автор
            18.06.2015 16:50

            Поверь, и на LibGDX я сейчас за пару часов смогу такую игру написать. Я пару месяц писал из-за того, что создавал игру после школы, когда время было. Т.е. бывало час, два поработаю, бывало вообще нет времени. Переписывал игру не раз.


            1. grcool
              18.06.2015 16:57

              Верю) Просто не вижу смысла писать приличный объем кода, если размер приложения будет настолько большим)
              Есть множество SDK на Lua, в которых все делается в разы проще и быстрее — за это платишь размером пакета. А тут выходит — не быстро, не просто и размер пакета огромный)


              1. DevAndrew
                19.06.2015 15:14

                Вот список игр сделанных на libgdx. В игры, которые я заходил — весят по 5 MB (Android). Так что автор поста где-то свернул не туда.


  1. roces
    17.06.2015 19:18

    Судя по статистике игра будет пользоваться популярностью на Android. Поздравляю и надеюсь она принесет вам приличный доход.
    На мой взгляд вы сделали очень правильный выбор в плане временем разработки, интересности игровой механики и монетизации.

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


    1. Mishok2000 Автор
      17.06.2015 19:51

      Ну я думаю, что данная игра уже особых денег не принесёт, хотя кто знает…
      Новый проект у меня на планку выше Crazy Crazy, но все же не огромный.
      Спасибо за напутствие.


  1. Redgard
    18.06.2015 12:48

    Желаю успехов в развитии но зачем гнаться за кросс платформенностью? Тем более даже если у вас нет Mac на вашем месте я бы делал приложения эксклюзивно под Android. И на размер файла это скажется с пользой. Сам я делаю свои приложения только под iOS и всегда стараюсь пользоваться уникальными преимуществами выбранной платформы.


  1. Goodkat
    18.06.2015 14:42

    Так как игра написана на LibGDX, то должно быть довольно просто переделать её под OS X и Windows, только добавить управление мышкой и клавиатурой и можно будет выпустить в Mac App Store и Windows Store.


    1. Mishok2000 Автор
      18.06.2015 14:50

      Кстати, да. Я об этом даже и не подумал. Спасибо за совет.


  1. AMDev
    07.07.2015 01:06

    Приятно видеть, как человек, не имея мака и apple девайсов, сумел выпустить игру в app store. Вы просто молодец!


    1. Mishok2000 Автор
      07.07.2015 01:24

      Спасибо. Но apple девайс у меня все же временно был, мне друг Ipad 2 одолжил на 2-3 дня.