Собери котов в Android 7 Nougat (не только)

Ярые фанаты Android знают, что в системе прячутся пасхалки. Не стала исключением и седьмая версия под названием Nougat. В ней можно активировать игру по сбору котов. Вам нужно изредка класть в пустую миску угощение и ловить пришедшего кота.
Сам процесс активации пасхалки подробно описан в блоге. Здесь же я расскажу, что находится под капотом.

В игре коты появляются с трехзначными числами. Теоретически котов может быть 1000 штук от 000 до 999 (на самом деле нет, в программе используется другой алгоритм, но для нас это не принципиально).
Мне стало интересно, как они хранятся в приложении. Поиск в интернете привел меня на ресурс, где выложены исходники пасхального яйца Easter Egg.
Позже на Гитхабе я нашел модифицированный код, который позволяет запускать игру как обычное приложение на любом устройстве, а не только на Android 7 — https://github.com/Abhinav1997/NekoCollector. Собранную версию из этих исходников можно найти Google Play по ключевым словам Neko Collector.
Второй пример удобнее изучать, так как там нет лишнего кода для активации пасхалки, который нам ни к чему.
Было не трудно догадаться, что основная магия происходит в классе Cat.

Усы, лапы, хвост — вот мои документы


Оказалось, что коты не хранятся в приложении в виде отдельных картинок. Вполне объяснимо, большое количество изображений раздует программу. В папке drawable в виде векторных ресурсов хранятся отдельные части кота. Например, так хранится хвост в файле tail.xml.
2540347092cc4409a3fdc28dda3a49d6.png
Аналогичным образом хранятся лапы, глаза, туловище, ошейник, бантик и т.д.
А затем всё это собирается в конструкторе внутреннего класса CatParts
        CatParts(Context context) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                body = context.getDrawable(R.drawable.body);
                head = context.getDrawable(R.drawable.head);
                leg1 = context.getDrawable(R.drawable.leg1);
                leg2 = context.getDrawable(R.drawable.leg2);
                leg3 = context.getDrawable(R.drawable.leg3);
                leg4 = context.getDrawable(R.drawable.leg4);
                tail = context.getDrawable(R.drawable.tail);
                leftEar = context.getDrawable(R.drawable.left_ear);
                rightEar = context.getDrawable(R.drawable.right_ear);
                rightEarInside = context.getDrawable(R.drawable.right_ear_inside);
                leftEarInside = context.getDrawable(R.drawable.left_ear_inside);
                faceSpot = context.getDrawable(R.drawable.face_spot);
                cap = context.getDrawable(R.drawable.cap);
                mouth = context.getDrawable(R.drawable.mouth);
                foot4 = context.getDrawable(R.drawable.foot4);
                foot3 = context.getDrawable(R.drawable.foot3);
                foot1 = context.getDrawable(R.drawable.foot1);
                foot2 = context.getDrawable(R.drawable.foot2);
                leg2Shadow = context.getDrawable(R.drawable.leg2_shadow);
                tailShadow = context.getDrawable(R.drawable.tail_shadow);
                tailCap = context.getDrawable(R.drawable.tail_cap);
                belly = context.getDrawable(R.drawable.belly);
                back = context.getDrawable(R.drawable.back);
                rightEye = context.getDrawable(R.drawable.right_eye);
                leftEye = context.getDrawable(R.drawable.left_eye);
                nose = context.getDrawable(R.drawable.nose);
                collar = context.getDrawable(R.drawable.collar);
                bowtie = context.getDrawable(R.drawable.bowtie);
            } else {
                // здесь код для старых версий
            }
            drawingOrder = getDrawingOrder();
        }

Так как вектор обладает замечательной возможностью менять заливку на лету, то в случайном порядке выбираем цвета и генерируем уникального кота. Главное — не переборщить. Не стоит красить одну лапу в чёрный, а вторую лапу в коричневый цвет.

Если запускать программу в обычном режиме, то коллекционирование котиков растянется на долгие часы. Поэтому подменяем код, который отвечает за интервал, установив его в 1 секунду. Быстро заполняем экран.
89fd57c326654b06b76b6b374449cfa5.png

Определённо стоит покопаться в коде приложение и изучить другие методы. Например, когда вы хотите поделиться пойманным котом в социальных сетях, то генерируется отдельное изображение PNG размером 512×512 хорошего разрешения на устройствах не ниже Android 6.0 Marshmallow. На старых устройствах изображение формируется через другой метод, и картинки получаются смазанными.
Для сравнения первая картинка, которую я получил на эмуляторе Android 7.
931eb560d82e4485a1d4f63fe0fdac4f.png

А это картинка, полученная на устройстве Android 4.4.2
8e8f63d1eed14b898ab2584965717546.png

Тем, кто изучает программирование под Android, пригодятся приёмы запуска служб с регистрацией планировщика JobSheduler, создание диалогов, использование SharedPreferences.

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

Комментарии (1)

  • 28 октября 2016 в 00:24

    0

    Дизайнер котов — гений, я не сразу заметил, что контур кота совпадает с лого андроида

© Habrahabr.ru