惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
月光博客
月光博客
B
Blog RSS Feed
C
Check Point Blog
WordPress大学
WordPress大学
T
Tailwind CSS Blog
GbyAI
GbyAI
H
Help Net Security
Y
Y Combinator Blog
I
InfoQ
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
美团技术团队
博客园 - 三生石上(FineUI控件)
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
A
About on SuperTechFans
G
Google Developers Blog
爱范儿
爱范儿
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
U
Unit 42
人人都是产品经理
人人都是产品经理

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Как я сделал на Flutter игру для разработчиков
submaps (Avi · 2026-05-12 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение8 мин

Охват и читатели852

Кейс

Всем привет! Меня зовут Амир Утеуов — я ML-инженер из Авито.

В этой статье поделюсь своей историей создания мобильной игры DevRush, пет-проекта, который перерос в игру на стенде IT-конференции CodeFest 2025.

Однажды у меня под рукой оказался датасет из иконок различных фреймворков и языков программирования. Так я решил разработать приложение, где нужно как можно быстрее находить и выбирать иконки языков программирования среди случайных иконок. До этого я не занимался разработкой и публикацией мобильных игр и приложений, но решил пройти весь путь с нуля.

Статью разделим на две части: в первой расскажу как создавал первую версию игры и с какими трудностями столкнулся, а во второй — как мы готовили игру к конференции.

Если подробнее, вот, что будет в первой части статьи: 

  1. Почему Flutter 

  2. Выбор языков программирования для иконок

  3. Геймплей

  4. Реализация проекта на Flutter

  5. Векторная анимация — главная сложность проекта

  6. Анимация экрана победы

  7. Сборка проекта

  8. Как пройти модерацию

  9. Выводы

  10. Что ещё посмотреть по теме

Почему Flutter

Начнем с самого главного — выбора на чём написать проект.

Мне нравится идея кроссплатформенных приложений. Благодаря такому решению приложение, написанное на одном языке программирования, будет работать аналогично и на мобильном устройстве (iPhone, Android), и на компьютере, и в Web. Из множества вариантов реализации самым подходящим мне показался Flutter.

Flutter — фреймворк для разработки кроссплатформенных приложений на языке программирования Dart. 

Dart — это С-подобный язык с некоторыми интересными фишками. Язык был создан Google для разработки кроссплатформенных приложений и значительно упрощает её за счет встроенных механизмов. Например, hot reload позволяет менять программный код, благодаря чему сразу меняются:

  • отображение;

  • логика работы экземпляра приложения в эмуляторе (или на реальном устройстве);

  • вычисляемые переменные в runtime проекта.

Во Flutter удобный набор виджетов для основных компонентов в едином дизайне, которые можно гибко настраивать. Механизм event loop, позволяет в одном потоке осуществлять асинхронную работу, управляя очередью поступающих событий.

Я прочитал туториалы по Flutter и нашел отличный бесплатный курс по Dart. Так без бэкграунда разработчика мобильных игр я принялся за разработку.

Следующим шагом я нарисовал схему приложения для реализации:

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

Писал игровую логику я сам, не зная про игровой движок Flutter Flame, сейчас бы использовал его.

Для начального таймера я поставил 16 секунд и этого было много (позже время было пересмотрено до 32 сек).

Тут еще больше контента

Тут еще больше контента

Выбор языков программирования для иконок игры

Я выбрал те языки программирования, которые мне казались распространенными. Чтобы игра была интересна и не слишком сложна, в нее были включены живые языки программирования (на которых еще разговаривают/программируют) и стабильные языки (релизы которых не находятся в тестировании).

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

Например, в датасет попал Fortran, так как для него выходят обновления и новые стабильные релизы. Но не был добавлен язык Mojo Script, потому что он был в альфа-тестировании на момент разработки.

Также я хотел добавить побольше бесплатных/открытых general-purpose языков программирования. Например, есть язык для SAP Abap или 1С, но они не является языками общего назначения (general purpose programming language). По тем же причинам в набор я не добавлял языки смарт-контрактов Solidity, Plutus и т.д. Различные языки запросов и разметки я тоже не добавлял в датасет.

Языков программирования совсем немного, но вот фреймворков/пакетов/библиотек предостаточно. Например, 700 тыс. в pypi Python, 18 млн в maven репозитории Java, 3.6 млн в npm JavaScript и т.д.

Поэтому из начального датасета я отобрал знакомые технологии: вышло около 250 иконок.

Геймплей

Напомню задумку: игроку необходимо как можно быстрее найти на экране иконку определенного языка программирования. 

Базово сложность устроена так: чем выше уровень — тем больше ЯП нужно найти среди большего количества иконок. Как я определил сложность по уровням: 

  1. На уровне «Junior» у каждого логотипа есть текстовая подпись — название языка или фреймворка/технологии.

  2. На уровне «Middle» у половины иконок нет подписей — нужно искать по образу в памяти.

  3. На уровне «Senior» у всех иконок нет подписей, только сам лого.

Проект был максимально простой, и, посмотрев на датасет, я понял, что неявно знаю 90% иконок.

Также я хотел, чтобы игра чему-то учила и давала новые знания тем, кто не знает часть технологий. Чтобы добавить определения технологий, написал скрипт на Python, который гуглит каждое название через DuckDuckGo API.

Получилось вот так:

ae04c06884a59f83e4c2eb07884e46f6.png

Все термины и определения изначально были на английском. Чтобы выпустить игру поскорее, на русском языке дублировать не стал.

8e1a1dff1106ba8a2bbc67351983da46.png

Таблица с информацией для игры

Реализация проекта на Flutter

После выбора стека разработки нужно было установить все необходимые зависимости в систему. Здесь уже можно столкнуться с проблемами, если у нас какая-то особенная конфигурация ОС.

На Flutter обычно создается проект из шаблона, где есть все необходимые классы и файлы настроек. Далее этот проект уже собирается из консоли VS Code для Web, Desktop, Android и iOS. Также можно использовать FlutLab, чтобы разрабатывать приложение в облаке, на случай если локально вы не можете/не хотите устанавливать все зависимости.

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

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

Начальный дизайн я сделал из дефолтных стилей, но отдельно добавил темную тему.

Необходимые файлы сохранил локально в проекте в assets — это папка, в которой мы храним ресурсы приложения. В ней я сохранил датасет, скачанные иконки из датасета и анимации.

В проекте используются PNG-изображения: они поддерживают прозрачный фон/alpha-канал. Однако некоторые иконки были недостаточно разборчивы на белом или же темном фоне, поэтому я добавил дополнительный фикс, чтобы при необходимости обвести изображение по контуру.

В первой версии проекта в названии картинки я закодировал нужную информацию. Файл назывался в формате: Name_Category_NeedBorder.png. Например, «Python_pr_nbrr.png» означало, что это картинка технологии «Python» из категории «Programming Language» и «nbrr» – не нужна граница.

«Nbrr» – достаточно длинный тег, который вряд ли встретится при добавлении новых изображений, но это потенциальный баг.

Основной экран состоял из класса игры, асинхронной загрузки поля игры и таймера в параллельном потоке.

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

Всего я добавил 64 уровня с постепенным увеличением количества технологий/иконок для выбора. Начиная с двух до восьми иконок на фиксированном поле 4x4.

Также я добавил режим контеста — при фиксированном random seed можно было запустить на разных устройствах одно случайное поле. Идея была в том, чтобы соревноваться с друзьями на скорость.

fe6a16cb6d42d07bf1c18b4e8df5abb3.png
19f783260878185819849410e4e1dcee.png

Экраны моей игры

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

Жми сюда!

Жми сюда!

Векторная анимация — главная сложность проекта

Дольше всего я рисовал анимацию разлетающихся иконок в векторном формате lottie animation, которые далее портировал в JSON. Анимации генерировал скриптом на Python, а эффект взрыва настраивал через easings

Иконки фреймворков в векторе частично я нашел, а частично нарисовал сам на Python.

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

Такую логику можно было полностью сделать на Flutter, рисуя и управляя объектами на чистом Dart (причем действительно каждый раз случайно), но тогда мне это показалось сложнее, поэтому оставил в to-do.

Анимация экрана победы

Сборка проекта

Flutter проект можно собрать в нескольких вариантах: Web, Desktop, Android, iOS, а также в Debug и Release.

Самое простое — debug-версия, которая подписывается debug-ключом. Она может быть использована через установку из apk файла на любом Android устройстве, если пользователь установит файл из неопределенного источника. Правда код будет без всех release оптимизаций, так как используется JIT компиляция.

Для публикации в Google Play сейчас необходим формат App Bundle (.aab). Это формат файла, который содержит в себе зависимости под разные устройства. Из него можно сконфигурировать и выгрузить только необходимые изменения под определенное устройство, а также загрузить только измененные части проекта, классы, ресурсы и т.д. Например, после обновления игры в маркете мне потребовалось скачать только обновление размером 14КБ вместо всего приложения весом 10 МБ.

Для сборки под iOS потребуется Mac OS и установленная XCode свежей версии, так как App Store периодически поднимает версию iOS, которую должно поддерживать приложение.

Сейчас существуют некоторые сложности публикации приложений в App Store, Google Play из России. Но, допустим, у вас уже есть аккаунты разработчиков в Google Play, App Store.

Из-за санкций сейчас российским аккаунтам нельзя создавать платные приложения — только бесплатные и без внутренней системы монетизации.

Сначала я опубликовал игру в Google Play: при первой публикации нужно подождать пару дней, чтобы ее проверили модераторы.

Самыми сложными были процессы настройки правильной подписи сертификатом приложений и корректное размещение всех ключей во всех файлах настроек.

Внутри Dart-проекта для каждой платформы создается папка со всей метаинформацией: Android, iOS, Web и так далее. В каждой папке отдельный проект, который может быть открыт соответствующей IDE, например, Android Studio и XCode. Правда, внутри, кроме настроек приложения и одного файла, который импортирует и вызывает Flutter приложение, особо ничего и нет. Основная работа и настройка идет в самом Flutter проекте.

Как пройти модерацию

При первой публикации в App Store игру отклонили по очень неожиданной причине. На одном из экранов игры при режиме игры OS была иконка операционной системы Android (среди Windows, MacOS, Linux, Debian и т.д.). Мне прислали скрин с выделенной иконкой Android и написали, что по правилам AppStore нельзя рекламировать продукты конкурентов.

95172a751de8c5def6a0f9b585f6cd2d.png

Это было забавно, ведь в контексте игры являлось уместным использованием логотипа.

К сожалению, мне пришлось удалить эту иконку. Этот случай наводит на мысль, что в App Store используются автоматические средства проверки приложений с детектом и распознаванием изображений, так как маловероятно найти именно такой экран с иконкой Android среди всех режимов и уровней игры.

Выводы

  1. Разрабатывать игры весело и интересно, в процессе я узнал много нового.

  2. Публикация игры в первый раз занимает приличное время.

  3. Я начал разработку, исходя из данных, и прошел путь от идеи до публикации, имея четкое представление схемы данных. Это помогло мне реализовать игру, не возвращаясь к изменениям различных частей.

  4. Flutter, в моём случае, показал себя с лучшей стороны. Функционала для моей простой игры было достаточно. Каких-то особых сложностей не возникло.

  5. Проблемы с производительностью Flutter обычно возникают, если делать какие-то тяжелые операции в шаге build event loop. Обычно помогает разделение логики вычислений.

  6. Программировать векторную lottie анимацию на Python достаточно ресурсозатратно, но увлекательно. В моем случае пришлось находить базовые элементы в SVG, потом писать логику анимации на Python в pylottie, экспортировать в .json и импортировать уже во Flutter приложение. Тема стоит отдельной статьи.

To be continued 

В данном виде игра существовала некоторое время, пока ко мне не подошли коллеги и не предложили использовать ее на стенде Авито на конференции Code Fest 2025. Как мы готовились, как был добавлен новый дизайн, веб-лидерборд и как прошла активность на конференция расскажу в следующей части!

Что ещё посмотреть по теме 

Кликни здесь и узнаешь

Кликни здесь и узнаешь