СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

H Написание игры под Android на C++ с помощью MoSync в черновиках

Примерно в декабре 2012 появилось острое желание спрограммировать самому игрушку для Андроида. Чтобы хоть она не падала и не была медленной и (сильно) убогой.

Дня два я просматривал табличку с возможными вариантами средств разработки. Требования — бесплатность, Андроид и Си-плюс-плюс. Я выбрал MoSync.

Результат: год работы над проектом, уход с работы и файл .apk на GooglePlay размером 1,7 Мб.


А теперь для желающих — подробно:
В 2011-ом у меня был миниатюрный опыт разработки для мобильных устройств на JavaScript-e.… Ну как разработки… точнее — реанимации сдохшего и заброшенного проекта. Опыт крайне неудачный, он надолго отбил интерес. А вначале был культурный шок от осознания: то есть я буду писать убогие игры (т.е. крайне далёкие от Starcraft-a и похожих), для людей, которые согласны заплатить две моих зарплаты за девайс, на котором можно будет играть только вот в такое убожество…

В декабре 2012 ситуация немного изменилась: в нашем «районном универсаме» появились дешёвые планшеты; я посмотрел количество скачивания популярных игр на GooglePlay, плюс у меня началась ломка от трёх месяцев без программирования — и я решился.

Первые шаги прошли легко: скачать и поставить студию MoSync, скомпилить программку-пример, порадоваться, что удалось запустить её в эмуляторе.
Ещё через какае-то время удалось запустить её на планшете.
Дальше был первый большой шок: дебаг программы в эмуляторе — он работал не всегда, и крайне непредсказуемо… Значения для переменных показывались не всегда правильные, формулы не поддерживались, содержание сложных структур не показывалось, и вообще программа иногда ломалась — не из-за кода, как выяснилось после бессонных ночей, а просто из-за глючного режима дебага.
Спасал только вывод информации на консоль.

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

А дальше началось «сделай сам».
Мне пришлось (и я это сделал) создать несколько Engine-ов. То есть, если я хотел добавить в проект какую-то «фичу» (фишку, примочку — особенность), мне нужно было знакомится с ней, изучать как её спрограммировать и вставить правильно, и какие у неё возможности. Дальше с этими «фичами» мне было удобнее работать через её Engine, при необходимости я изменял его… (без наследования, каюсь)

Первым был создан «Screen-Engine» — меня категорически не устраивало делать программу под какой-то конкретный размер экрана — я хотел работать с виртуальным экраном, а как его вывести на реальный — проблема Screen-Engine-а. Так же он конвертировал касание пользователя к экрану в виртуальные координаты, делал scroll (прокрутку виртуального экрана по меньшему реальному), pinch-zoom-in и pinch-zoom-out (изменение масштаба двумя пальцами). Это заняло больше всего времени — примерно месяца 3-6 — включая такие примочки, как замирание если аппликация не активна (чтоб не жрать батарейку и процессорное время зря) и показ пользователю определённых мест — «смотри: это — карта, отсюда начинаешь ты, а враг — примерно во-о-он там».

Далее поляки выпустили FreeCiv (бесплатная версия Цивилизации) под Android, и я проверил, будет ли у меня так же всё тормозить, если я буду отрисовывать карту «стратегии» из тайлов… Результат мне понравился, я решил обязательно вернуться к этой теме, но позже.
Затем (это был апрель-май, год назад) я решил выпустить игру попроще, ибо запутался в формулах тригонометрии и кинематики… Поскольку близкие во всю играли в Филлер, я решил делать его — будут проверять-тестить. (Надежды не оправдались.) Дабы не выпускать «ещё один HelloWorld», нужно было придумать, чем моя игра будет выделятся. Я решил, что раз это на Си — а значит работать будет быстрей, чем Ява (минусующим: это сугубо моё личное мнение) — то это будет нефиксированный размер экрана, поле — больше, чем у «конкурентов», какая-то анимация, и более «умный» ИИ.
Плюс я почувствовал, что нужна более простая игра, чтобы создать и проверить, «обкатать» все будущие Engine-ы — было похоже, что их понадобится немало.

Вторым Engine-ом стал Multi-Language-Engine. Он смотрел локаль (страна-язык мобильного устройства), загружал нужный язык (если не было — тогда дефолтный) и делал конвертации: UTF-8 (Multi-Byte-String) в Unicode и обратно — дело в том, что на экран игры (где отрисовка графики) нужно было выводить в Юникоде, а в менюшки — в UTF-8.
Так же Multi-Language-Engine формировал сообщения с параметрами — типа «у вас xxx дерева, yyy камня и zzz золота», для английского — «You have xxx wood, yyy stone and zzz of gold», и так — для всех поддерживаемых языков.
В начале выяснилось (после нескольких бессонных ночей), что Кхмерский язык не поддерживается — у шрифтов эмулятора и девайса нету букв для этого языка — ни в Юникоде, ни в UTF-8.
В конце выяснилось, что язык Хинди (а их 600-700 миллионов человек) не загружается корректно в UTF-8 (там более 4 байт на символ), но всё хорошо, если загружать его в Юникоде — т.е. мне повезло, что разрабатывал этот «языковой движок» для загрузки из обоих кодировок.

Дальше была работа с менюшками и диалогами — выяснилось (после долгих бессонных), что в MoCync элементы диалогов (виджеты) нужно не стирать, как в Си++, не обнулять, как в Яве, а оставлять нетронутыми — только тогда система их корректно сама… утилизирует.
Мне не понравилось, что у чек-бокса нажимается только кнопка, а не плюс ещё вся фраза, как в Виндах — пришлось писать своё…
Я не нашёл нормального элемента для набора числа — пришлось не только делать «своё», но ещё и добиваться, чтоб он был определённой ширины; какой — не знаю, узнаю кода он будет показан — от шрифта зависит…
Последними элементами по желанию были «рамочка вокруг чего-скажут» и горизонтальная линия (в принципе, та же рамочка, но на всю ширину).
После всех этих нововведений диалоги и менюшки перестали корректно уничтожаться, но эти было не критично — тихо висели в памяти.

AudioEngine — пляски с бубном продолжаются. Потому, что выяснилось, что не все функции MoSync корректно работают. Разработчики MoSync перестали отвечать и исправлять ошибки, потому что MoSync обанкротился. Но поскольку сил и времени уже было вложено много, то… Результат: громкость каждого звука не регулируется, но зато их можно не только останавливать и проигрывать, но даже ставить на паузу — это нужно, если аппликация не активна. Добиться этого удалось склеив стабильную версию библиотек студии «3.3.1» и «ночного билда с фиксом». Правда при этом аппликация перестала билдиться в Debug (отладочном) режиме. Но… он слегка полезен только запуская аппликацию в эмуляторе, а звуки и менюшки-диалоги в эмуляторе не работают — только на реальном устройстве.
Причина создания AudioEngine — автоматическая загрузка звуковых ресурсов, их более удобное проигрывание (и прочие функции), автоматические пауза (если аппликация не активна) и resume (возобновление проигрышей звуков), автоматическая работа с памятью — освобождение памяти звуков, что больше не используются; возможность проигрыша одного и того же звука одновременно более одного раза.

«Ёжики кололись и плакали, но продолжали...»

Я решил добавить не просто стены, а лабиринт — спасибо пользователю aivanov за публикацию его генератора лабиринтов aivanov.com/maze-generator/ — я его использовал.
Затем, чтобы играть стало ещё интересней, я добавил «fog of war» (туман войны), чтобы… интриговать пользователя «а туда ли я иду» в случае лабиринта, и «а далеко ли идут эти слепленные ячейки одного цвета» при выборе цвета.
После этого пришлось переделывать анимацию, дабы неизведанные ячейки «открывались» красиво; отдельно пришлось поработать с рамками вокруг ячеек; к сожалению, этого стало почти не заметно после того, как были сделаны картинки=битмапы на ячейки.

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

1: Большая страшная картинка
image


Результат (после года работы) мне не понравился, конечный вид:

2: Большая картинка с белыми боками
image


3: Большая картинка без белых боков
image


Я использовал один тайл 200х200 пикселей, при старте программы делались его копии меньших размеров. Если этот тайл нужен большего размера — он увеличивается программно прямо во время отрисовки — имхо тормозит не сильно. Но тогда время старта программы увеличилось до катастрофических 7+ секунд. Плюс тайлы выглядели некрасиво при изменении масштаба. Пришлось изменять их размер вручную, со всеми экспериментами это заняло пару дней, сам ресайз 200 png — 2-4 часа. Зато время старта программы уменьшилось до нормального — 2-3 секунды.

Один из последних штрихов — использование не стандартных, а «красивых» цветов. Для этого я почувствовал (типографским прошлым), что нужно использовать не RGB а HSL цветовую модель… тогда насыщенность и светлота остаются примерно одинаковыми, а тоны цветов ячеек выбираются, деля 360 градусов на количество цветов на карте.

Последние изменения — отдав другу тестировать новоиспечённую игруху, состоялся разговор как по «испорченному телефону»:
— Меню нажми. — Где?
— Ну кнопку «меню». — Где она у тебя?
— Она у тебя на девайсе!
… выяснилось, что не все девайсы имеют кнопку «меню» на корпусе. Пришлось добавить на экран кнопки «Menu» и на всякий случай — «Back».

Следующее — релиз на Google Play. Кратко, новое для меня: мне было интересно, как быстро мая аппликация станет заметна — без раскрутки. Просто задавая поиск по её названию. Результаты: почти моментально игра находилась по редкой фразе «MoSync». Через неделю — по «Flood Filler». По «Color Flood Filler» (её название) — только через две недели после её появления на Google Play. Так же по этой фразе (на чужом компе) неожиданно выскакивали скриншоты из игры с пометкой «добавлено 3 дня назад».

Скриншоты для описания игры на Google Play: требуются для «телефона», 7-дюймового планшета и для 10-дюймового планшета. Нашёл, что принимаются размеры: 320x480, 480x800, 480x854,1280x720 и 1280x800.
Я «вкинул» скриншот 320x480 в секцию для «телефона», 480x800 — для 7-дюймового планшета и 1280x800 для 10-дюймового планшета. Результат мне не понравился: и на телефоне (с экраном 240x320) и на планшете (с экраном 480x800) я вижу все скриншоты, из всех трёх групп. Вопрос: что я делаю не так?

Следующие задачи — перевод игры на заявленные 42 языка (с помощью гугль-переводчика, если на translatewiki.net проект не пустят; файл для одного языка занимает примерно 4000 символов, 170 строк); и, видимо ещё важнее — перевести описание игры для Google Play.
После этого, в конце, планирую вставить инфу, как отблагодарить автора финансово (номера счетов кредиток) — правда подозреваю, что гипотетический донат не окупит не только год работы, но даже хотя бы то время, что я буду эту инфу вставлять. Вопрос: насколько это безопасно?

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

Адрес игры на Google Play: play.google.com/store/apps/details?id=com.mosync.app_FloodFiller
Любые предложения и конструктивная критика — принимаются. А за помощь буду вообще благодарен! :)

Обновления после первой публикации неделю назад:
Добавлена возможность регулировать насыщенность цвета для ячеек — «цвета слишком яркие» — этого не могло быть на экран моего планшета. :)
Добавлена возможность регулировать размер шрифта.
Добавлены музыка при победе и проигрыше; файл от добавления двух mp3-ёшек разбух до 2,5 Мб. Вопрос: могу ли я использовать известную мелодию в своей бесплатной игре? Нужно ли что-то предпринять дополнительно?
На данный момент кроме русского и английского — игра переведена на испанский, немецкий, японский, корейский и литовский языки.
Извиняюсь перед модераторами: это мой второй пост, когда 3 года назад делал первый — хаба «Я пиарюсь» ещё не было — я не знал, что теперь нужно вставлять его.
Если карму не понизят очень сильно — в течении года хотел бы рассказать тут о своей второй «игрушке» для Андроида.

Вопрос: какое средство разработки порекомендуете Вы, исходя из требований: бесплатно, Андроид и C++?
Спасибо за внимание. Отдельное спасибо — «прикармившим».

комментарии (12)

–5
+1 –6
SAKrisT ,  

Рекомендую Qt.

0
zagayevskiy ,   * (был изменён)

Сорри, не в ту ветку ответил.

А почему именно С++? Google в рекомендациях к Android NDK говорит — не стоит использовать нативные средства только из-за предпочтения писать на С/C++.

–1
SAKrisT ,  

Автор статьи задал вопрос:

Вопрос: какое средство разработки порекомендуете Вы, исходя из требований: бесплатно, Андроид и C++?

Я порекомендовал в соответствии запросам.
+1
zagayevskiy ,  

Я же написал, что ответил не в ту ветку. Это был вопрос к топикстартеру

0
SP_77 ,  

Видимо, проблема в моём незнании: я не очень представляю, как написать шуструю игрушку на Яве :)
В том числе и поэтому я создал свой Филлер — чтобы сравнить его (производительность) с остальными Филлерами, написанными на Java.

0
Bringoff ,   * (был изменён)

Рекомендую не мучаться и писать на java. Ну, или если хотите именно игры, то можно cocos-2dx — бесплатно, С++. Чем менее популярная технология используется, тем больше проблем, требующих собственных костылей, будет возникать.

0
SP_77 ,  

Не в последнюю очередь меня интересует скорость отрисовки экрана.
Написав в MoSync я могу выводить примерно 500 объектов со скоростью 20 fps.
Вопрос-1: насколько быстро происходит отрисовка в программах, созданных в других IDE?
Вопрос-2: Порекомендуйте пожалуйста игры, созданные в Qt, cocos-2dx, unity, corona — посмотреть скорость отрисовки в них.
Вопрос-3: Почему «минусуют» ответ об «Qt» — это заведомо плохой продукт, или это… эмоциональное?

0
Bringoff ,   * (был изменён)

Минусы потому, что qt в первую очередь для приложений, к тому же андроид разработка на нем пока сыровата.
Игры, написанные с помощью фреймворков, можно найти на сайтах этих фреймворков. К примеру, вот на cocos2d play.google.com/store/apps/details?id=com.booyah.birds

0
zagayevskiy ,  

Что вы подразумеваете под «объектом»? 500 объектов — это сколько примитивов? Я, допустим, выводил 1000+ треугольников (С++, NDK, OpenGL es 2.0), 60 fps на Nexus 7 и HTC One S, 30 fps на Samsung galaxy Y.

0
SP_77 ,   * (был изменён)

Объект = (цветной) прямоугольник. И вроде бы если вместо прямоугольника использую картинку (с альфа-каналом) — получается примерно столько же.… Вроде я не совсем через OpenGL (1.0) вывожу — не умею.

Ага — C++… А на Яве какой скорости можно достичь?

0
zagayevskiy ,  

В Java есть обертки к OpenGL, если писать на нем, я думаю, отличий особых не будет.

Вроде я не совсем через OpenGL (1.0) вывожу — не умею.
Научитесь, в чем проблема?
Посмотрите на libgdx (примеры), там можно писать без знания OpenGL. Если вас так волнует fps, то думаю он там будет близок к нативному. Заодно развеете предубеждения насчет скорости джавы.
ИМХО, 20 fps на 500 прямоугольниках можно достичь даже используя Android Canvas.
0
Suvitruf ,  

Плюсую к libgdx. Если интересно, я шарил в своё время сорсы Bomberman'а на этом движке. При 300+ npc fpc был выше 30.