Анимации в Android по полочкам (Часть 1. Базовые анимации)
Анимация преобразований
Анимация может выполняться в виде ряда простых преобразований — изменение позиции, размера, угла вращения и уровня прозрачности на поверхности объекта View. Например, у компонента TextView можно перемещать, вращать, уменьшать или увеличивать текст. Если TextView имеет фоновое изображение, оно будет преобразовано наряду с текстом. Пакет android.view.animation содержит необходимые классы для анимации с промежуточными кадрами.
Основные классы анимации и их соответствия в XML:
Команды анимации определяют преобразования, которые необходимо произвести над объектом. Преобразования могут быть последовательными или одновременными. Каждое преобразование принимает набор параметров, определённых для этого преобразования (начальный размер, конечный размер при изменении размера, стартовый угол и конечный угол при вращении объекта и т. д.), а также набор общих параметров (например, начального времени и продолжительности). Если требуется сделать несколько преобразований одновременно, им задают одинаковое начальное время. Если требуется сделать последовательные преобразования, задается их время старта плюс продолжительность предыдущего преобразования.
Последовательность команд анимации определяется в XML-файле (предпочтительно) или в программном коде.
Создание анимации в XML-файле
XML-файл анимации размещают в каталоге res/anim/ вашего проекта. Файл должен иметь единственный корневой элемент: это будет любой из элементов , ,
По умолчанию все элементы применяются одновременно. Чтобы запускать элементы последовательно, необходимо определить атрибут startOffset и указать значение в миллисекундах, например:
Атрибуты анимации
- duration — продолжительность эффекта в миллисекундах
- startOffset — начальное время смещения для этого эффекта, в миллисекундах
- fillBefore — когда установлен в true, то преобразование анимации применяется перед началом анимации
- fillAfter — когда установлен в true, то преобразование применяется после конца анимации
- repeatCount — определяет число повторений анимации, можно использовать значение infinity (бесконечность)
- repeatMode — определяет поведение анимации при ее окончании. Возможные варианты: restart (перезапустить без изменений) или reverse (изменить анимацию в обратном направлении)
- zAdjustment — определяет режим упорядочения оси Z, чтобы использовать при выполнении анимации (нормаль, вершина или основание)
- interpolator — определяет постоянную скорости, которая описывает динамику визуальной деятельности в зависимости от времени или, говоря простым языком, определяет скорость изменения анимации. Можно использовать любой из элементов подкласса интерполятора, определенных в R.styleable, например: android_interpolator=”@android:anim/decelerate_interpolator”
Элемент
Элемент — контейнер, который может содержать другие элементы. Представляет класс AnimationSet. Поддерживает атрибут shareInterpolator, который при значении true указывает на возможность совместного использования этого интерполятора для всех дочерних элементов.
Элемент
Постепенно изменяющаяся анимация прозрачности при помощи AlphaAnimation. Поддерживает следующие атрибуты:
- fromAlpha — начальное значение прозрачности объекта;
- toAlpha — конечное значение прозрачности объекта;
Атрибуты содержат значение прозрачности от 0 до 1 типа Float, где 0 означает полную прозрачность объекта.
Элемент
Элемент управляет анимацией изменения размеров объекта и представляет класс ScaleAnimation. Вы можете определить центральную точку изображения (закрепить центр анимации изображения), относительно которой будет изменяться масштабирование объекта. Элемент поддерживает следующие атрибуты:
- fromxScale — начальный масштаб по X. Допустимы значения от 0 до 1 типа Float
- toxScale — конечный масштаб по X. Допустимы значения от 0 до 1 типа Float
- fromYScale — начальный масштаб по Y. Допустимы значения от 0 до 1 типа Float
- toYScale — конечный масштаб по Y. Допустимы значения от 0 до 1 типа Float
- pivotX — Х-координата закрепленного центра. Описывает центральную точку масштабирования в процентах от ширины от 0% до 100%
- pivotY — Y-координата закреплённого центра. Описывает центральную точку масштабирования в процентах от высоты от 0% до 100%
Элемент
- fromXDelta — начальное положение по X
- toXDelta — конечное положение по X
- fromYDelta — начальное положение по Y
- toYDelta — конечное положение по Y
Атрибуты должны быть в любом из следующих трёх форматов:
- Абсолютное значение
- Значения в процентах от -100% до 100%
- Значения в процентах от -100%p до 100%p, где p указывает процент относительно его родителя.
Слайд-шоу
Например, для эффекта слайд-шоу, когда один элемент выталкивает полностью другой элемент, реализуется двумя анимациями справо-налево или слева-направо.
Элемент
Элемент предназначен для анимации вращения и представляет класс RotateAnimation. Поддерживает следующие атрибуты:
- fromDegrees — начальный угол вращения в градусах
- toDegrees — конечный угол вращения в градусах
- pivotX — координата X центра вращения в пикселах;
- pivotY — координата Y центра вращения в пикселах
Примеры с анимацией преобразований
Можно создать несколько файлов анимации и применять их для одного объекта. Рассмотрим работу анимации на примере прямоугольника. К сожалению, у меня не заработал пример с изменением прозрачности (alpha), может вам повезет больше. (Как рассказал один из читателей, пример работает на эмуляторе 2.1, а на эмуляторе 2.3.3 уже нет).
Создайте новый проект и в каталоге res/anim/ проекта создайте пять файлов с XML-анимацией: alpha.xml, rotate.xml, scale.xml, translate.xml и файл combination.xml, в котором мы будем использовать комбинацию различных объектов для создания смешанной анимации.
alpha.xml
rotate.xml
scale.xml
translate.xml
combination.xml
shape.xml
Фигуру прямоугольника для анимации определим в файле shape.xml, который будет находиться в каталоге res/drawable.
Разметка
Перейдем к разметке основной формы приложения (main.xml). Поместим элемент ImageView:
Анимация
Анимация запускается в коде следующим образом: надо создать объект Animation через вызов метода AnimationUtils.loadAnimation() и передать ему в качестве параметра контекст активности и ссылку на XML-файл анимации. Затем запускается анимация через метод View.startAnimation(), передавая в него объект Animation:
AnimationListener
В классе Animation есть интерфейс AnimationListener. Интерфейс AnimationListener позволяет создать обработчик событий, который срабатывает в начале или при завершении анимации. Используя его, вы можете совершать какие-либо операции, прежде чем (или после того как) анимация закончит работу. Это может быть изменение содержимого представления или последовательный показ нескольких анимаций.
У интерфейса AnimationListener есть три метода обратного вызова:
- onAnimationEnd()
- onAnimationRepeat()
- onAnimationStart()
В этих методах можно реализовать код обработки события запуска, окончания и перезапуска анимации. Например, при окончании анимации можно сделать объект анимации невидимым, а при запуске снова отобразить на экране:
Вызовите метод setAnimationListener() из объекта Animation и передайте ему в качестве параметра реализацию интерфейса AnimationListener, при необходимости переопределив методы onAnimationEnd(), onAnimationStart() и onAnimationRepeat().
В основном классе создадим меню из пяти пунктов, соответствующих каждому типу запускаемой анимации: Alpha, Scale, Translate, Rotate и Комбинация. В качестве идентификаторов пунктов меню используем идентификаторы ресурсов XML-файлов анимации, упростив тем самым структуру метода onOptionsitemSeiected(), вызываемого при выборе пункта меню.
Анимация графических файлов
Анимация для графических файлов ничем особым не отличается от анимации для графических фигур. Рассмотрим на примере анимацию графического объекта, отображаемого в ImageView. Создайте новый проект и найдите какой-нибудь графический файл с изображением кота (но не собаки, иначе работать не будет!).
В XML-файле анимации создадим следующую структуру: используем элемент для растягивания изображения и вложенный контейнер , в котором определим два дочерних элемента и для одновременного вращения и изменения размеров объекта. Данный файл необходимо сохраним в каталоге res/anim/ под любым именем, например, crazycat.xml
crazycat.xml
В файле разметки поместим кнопку для запуска анимации и один элемент ImageView для нашего изображения.
Осталось написать программный код:
При нажатии кнопки изображение кота сначала плавно растянется по горизонтали, затем одновременно повернется и уменьшится в размерах, после чего вернется в исходное состояние.
Независимо оттого, как анимация изменяет размеры объекта или перемещает его на плоскости, границы элемента View, в который загружено изображение, останутся неизменными: ваша анимация не будет автоматически корректировать размеры представления для размещения объекта. Если анимация выйдет за границы родительского представления, произойдет отсечение объекта анимации.
Анимация группы представлений
Анимацию можно сделать и для нескольких представлений, объединив их в группу. Например, поместив представления в контейнер LinearLayout, причем можно использовать не только графические, но и текстовые представления.
Принцип анимаци останется тем же. В файле разметки приложения разместите дочерний контейнер LinearLayout, в котором разместите ImageView с изображением и TextView с надписью. Для дочернего контейнера обязательно присвойте идентификатор, по которому вы сможете загрузить его в код программы и использовать для анимации.
Код класса практически не будет отличаться от предыдущего примера, за исключением того, что мы работаем с анимацией не отдельного представления, а с анимацией группы представлений:
Как ускорить Android: отключение анимации
С каждой версией Android становится всё шустрее и шустрее. Систему постоянно оптимизируют, и на практике это даёт простой факт: смартфон Galaxy Nexus, который я купил 2 года назад, сейчас работает в 1.5 раза быстрее, чем при покупке. С выходом KitKat 4.4 ситуация становится ещё лучше, но пока новинка анонсирована лишь для небольшого числа устройств, а мы поищем иные пути повышения производительности своих смартфонов.
Реальность такова, что анимация интерфейса, изначально добавленная для сглаживания переходов между приложениями и меню, сейчас создаёт нежелательный эффект — мощности смартфонов возросли, всё открывается и переключается очень быстро, и анимация в некоторых случаях становится субъективно излишней. К тому же, за годы ты уже так насмотрелся на систему, что все эти графические изыски уже не впечатляют. Я просто хочу максимально быстро перейти из А в Б.
Итак, для избавления от тормозящих навигацию элементов анимации мы идём в Настройки -> Для разработчиков.
Если такого пункта у вас нет, значит он не включен (К.О.). Для его активации открываем нижний пункт в Настройках под названием О телефоне. Находим здесь пункт Номер сборки и тапаем по нему 7 раз. Произойдёт магия и откроется режим разработчика.
Возвращаемся в Настройки и заходим в Для разработчиков. Тут скролим вниз до раздела Рисование. Нас интересуют 3 параметра: Окно: масштаб, Переход: масштаб и Скорость анимации.
По умолчанию значение этих параметров равно 1, но мы выставим их в 0, то есть отключим анимацию.
Для того чтобы изменения вступили в силу, можно просто перезагрузить мобильное устройство, либо тонко ребутнуть лаунчер. Идём в Настройки -> Приложения. Переходим на вкладку Все и находим в списке Launcher.
Делаем его остановку, а затем снова запускаем. Готово.
Как можно ускорить анимацию на Android устройстве
На устройствах Android отображаются анимации при переходе между приложениями, окнами и различными меню. Анимации часто выглядят гладко, но они занимают много времени, а иногда даже могут затормозить телефон, если у него мало ресурсов.
Хорошей новостью является то, что Вы можете ускорить или отключить эти анимации, чтобы Ваш телефон чувствовал себя быстрее. Это ключевое слово здесь, потому что это на самом деле не ускоряет работу Вашего телефона, а просто заставляет создает видимость ускорения, поскольку меню и многое другое загружаются быстрее.
Однако, если Вы решите отключить анимацию, это уберет часть загрузки с CPU/GPU, что, безусловно, поможет уменьшить отставание в системах с меньшими ресурсами.
Шаг первый: включить параметры разработчика
Если у Вас еще нет параметров разработчика, Вам нужно их включить. У нас уже есть подробная инструкция о том, как это сделать, но вот кратко:
- Открыть Настройки > О телефоне (Настройки > Система > О телефоне в Oreo)
- Нажмите номер сборки 7 раз
- Вы теперь разработчик!
Параметры разработчика теперь будут новой записью в меню «Настройки» («Настройки» > «Система» > «Параметры разработчика» в Oreo).
Шаг второй: измените анимацию
Перейдите в меню «Для разработчика», затем прокрутите вниз до раздела «Рисование».
Здесь найдите три настройки: Анимация окон, Анимация переходов и длительность анимации.
Как Вы их измените зависит от Ваших предпочтений, но мне лично нравится видеть некоторую анимацию, потому что она просто делает все более гладко. Таким образом, я установил все три значения на 0.5x, чтобы ускорить их от опции по умолчанию (1x), не отключая их полностью.
Если Вы пытаетесь сделать устройство с низкими ресурсами немного более быстрым, то полностью отключите все анимации. Это должно заставить телефон чувствовать себя быстрее и меньше ощущать малую производительность оборудования.
Как создать анимацию в Android приложениии?
Продолжая серию уроков по Android, я решил показать вам как можно добавить анимацию для простой картинки.
В данном уроке мы научимся создавать несколько анимация на картинку. Для того чтобы выполнить этот урок вам потребуется создать Android проект c:
Minimum required SDK = 3.0
Target SDK = 4.2
Шаг 1. Создаем внешний вид
Создаем layout main_layout.xml (srcmainreslayoutmain_layout.xml) cо следующим содержимым:
И в string.xml добавим следующие строки:
И теперь в srcmainresdrawable добавляем картинку android_img.png:
В итоге наше приложение будет выглядеть так:
Шаг 2. Создаем Activity
Теперь давайте добавим Activity для нашего layout, для этого в srcmainjavacomdevcolibrianimationimage создаем новое Activity MainActivity.java со следующим содержимым:
После этого ваш layout можно будет увидеть после запуска приложения, но незабывайте настроить activity в AndroidManifest.xml.
Теперь все будет работать
Шаг 3. Создаем анимации
В Android анимации представлены в виде анимационных ресурс файлов, а точней в виде XML файлов, в которох описанно поведение элемента на который будет применена данная анимация.
Анимация №1
Для начало создадим самую простую анимацию для первой кнопки.
Она будет смещать наже изображение влево, потом возвращать на исходное положение. Для того, чтобы создать анимацию в папке res создайте новую ресурсную папку anim:
После этого в папке anim создаем Animation resource file с именем animation_one.xml и содержимым:
Как видите все начинается с тега set, он является стандартным тегом для всех анимационных русурс файлов, а вот тег translate – это уже наша анимация, где:
android:toXDelta – это смежение по оси X в лево;
android:duration – это продожытельность перемещения, чем больше duration, тем медленей будет двигаться изображение.
Анимация №2
Теперь создадим в тойже папке anim новый ресурс файл с именем anumation_two.xml и содержимым:
Как видите в этой анимации мы используем тег rotate – он позволит нам заставить наше изображение сделать поворот, в нашем случае на 360 градусов.
Давайте рассмотрим детальней атрибуты свойства rotate:
android:pivotX – это говорит о том, что точка повората будет в центре изображения, поэтому оно просто сделает круговой поворот;
android:fromDegrees- тут мы указываем начальное угловое положение, в градусах;
android:toDegrees – а тут конечное угловое положение, в градусах;
android:duration = это продолжительность анимации чем больше оно будет тем медленей будет анимация.
Анимация №3
Теперь расмотрим немного сложней анимацию. Для этого создаем 3-ю анимацию и называем её animation_three.xml:
Тут мы уже видим несколько анимационных свойств объеденены в одну анимацию. Вы уже наверное заметели, что мы сново используем анимацию rotate, но помимо её тут есть и новая анимация scale.
scale – позволяет сделать динамическое изменение размера компонента, в нашем случае картинки.
В данном сценарии мы сначало выполняем увеличение изображения, и в этот же момент поворачиваем его на 360 градусов и на половине поворота изображение перестает увеличиваться, и начинает уменьшаться.
android:duration – продолжительность анимации;
android:fromXScale – начальная позиция смещения анимации по оси X;
android:fromYScale – начальная позиция смещения анимации по оси Y;
android:pivotX – определяет начальную точку изменения размера по оси X;
android:pivotY – определяет начальную точку изменения размера по оси Y;
android:startOffset – количество миллисекунд задержки анимации после запуска;
android:toXScale – размер смещения по оси X;
android:toYScale – размер смещения по оси Y.
Шаг 4. Подключение анимаций
Теперь давайте подключим анимации на картинку, но они будут срабатывать после клика по кнопки, где каждая кнопка будет отвечать за определёную анимацию.
Вот полный код MainActivity:
Методы onAnimationImageOne, onAnimationImageTwo, onAnimationImageThree вызываются в main_layout на каждой кнопке в свойстве android:onClick.
Animator — инструмент для создания анимаций на Android
Что такое Animator?
Статья была впервые опубликована здесь.
Немного истории. С момента запуска платформы Android существовал фреймворк View Animation. Предназначался он, как следует из названия, для анимаций. Но производительность устройств в конце нулевых была настолько низкой, что о красивых анимациях никто особо не думал, поэтому фреймворк не был удобным и гибким. Он имел только четыре типа анимации (TranslateAnimation, AlphaAnimation, ScaleAnimation, RotateAnimation), класс, позволяющий их комбинировать (AnimationSet), а также способность работать только с классами, унаследованными от View.
В Android 3.0 появился куда более гибкий фреймворк Property Animation. Он умеет изменять любое доступное свойство, а также может работать с любыми классами. Его основным инструментом является Animator.
Animator — это тип классов, предназначенных для изменения значений выбранного объекта относительно времени. Грубо говоря, это инструмент для управления потоком заданной длительности, который изменяет определённое свойство от начального значения к конечному. Таким плавно меняющимся свойством в анимации может быть, например, прозрачность.
Классы, унаследованные от Animator
ValueAnimator (наследуется от Animator)
В самом простом варианте мы задаём этому классу тип изменяемого значения, начальное значение и конечное значение, и запускаем. В ответ нам будут приходить события на начало, конец, повторение и отмену анимации и ещё на два события, которые задаются отдельно для паузы и изменения значения. Событие изменения, пожалуй, самое важное: в него будет приходить изменённое значение, с помощью которого мы и будем менять свойства объектов.
Посмотрите на изменение alpha с его помощью:
ObjectAnimator, наследуется от ValueAnimator
Это класс, призванный упростить работу с ValueAnimator. С ним вам не нужно вручную изменять какое-либо значение по событию изменения — вы просто даёте Animator’у объект и указываете поле, которое вы хотите изменить, например scaleX. С помощью Java Refliction ищется setter для этого поля (в данном случае — setScaleX. Далее Animator самостоятельно будет менять значение этого поля.
С помощью ObjectAnimator изменение alpha будет выглядеть так:
У класса View есть несколько свойств специально предназначенных для анимирования с помощью Animator:
- прозрачность (View. ALPHA )
- масштаб (View.SCALE_X, View.SCALE_Y)
- вращение (View. ROTATION , View.ROTATION_X, View.ROTATION_Y)
- положение (View.X, View.Y, View.Z)
- положение отображаемой части (View.TRANSLATION_X, View.TRANSLATION_Y, View.TRANSLATION_Z)
AnimatorSet (наследуется от Animator)
Это класс, позволяющий комбинировать анимации различными способами: запускать одновременно или последовательно, добавлять задержки и т.д.
Это отдельный класс. Он не наследуется от Animator, но обладает той же логикой, что и ObjectAnimator для View, и предназначен для лёгкого анимирования какой-либо View без лишних заморочек.
Вот так с его помощью можно изменить alpha:
Как мы начали использовать Animator
Около года назад передо мной встала задача сделать анимацию при клике на элемент. Вот такую:
Не то чтобы я не делал анимаций прежде, но на аутсорсе они редко нужны. Поэтому я загуглил Animation Android. Первые пять ссылок довольно подробно описывали, как делаются анимации, и я приступил. Вот первый результат:
Код получился малопонятным, что подтолкнуло меня к поискам иного подхода в составлении последовательности анимаций. Решение было найдено на StackOveflow. Идея такая: помещать в последовательности анимаций каждую последующую анимацию в AnimationSet со сдвигом, равным сумме длительностей предыдущих анимаций. Получилось гораздо лучше, чем было:
Код стал понятнее и читабельнее, но есть одно «но»: следить за сдвигом у каждой анимации довольно неудобно даже в такой простой последовательности. Если добавить ещё несколько шагов, то это станет почти невыполнимой задачей. Также важным минусом такого подхода стало странное поведение анимации: размер анимированного объекта, по непонятным для меня причинам, был больше, чем при обычной последовательности анимаций. Попытки разобраться ни к чему не привели, а вникать глубже я уже не стал — подход мне всё равно не нравился. Но я решил развить эту идею и разбить каждый шаг на отдельный AnimatorSet. Вот что вышло:
AnimatorSet в AnimatorSet
Некорректная работа анимации, плохой подход, всё плохо. Вновь я обратился к Google, и наткнулся на то, что Animation уже является Legacy code, то есть устарел и не поддерживается, хотя и используется.
Я понял, что нужно делать анимации совершенно иначе. И вот на просторах Android Developers я наткнулся на Animator. Попытка сделать анимацию с его помощью выглядела так:
Анимация работала безупречно, а значит, поиски можно считать оконченными. Единственное, что при работе с Animator нужно помнить, не запущен ли уже какой-то Animator для конкретной view, потому что в противном случае старый продолжит выполнятся, как ни в чем не бывало.
Глубже в Animator
Я начал поиски того, что ещё интересного можно сделать с помощью Animator. Полёт мысли привёл меня к следующему:
При нажатии на кнопку одновременно выполняется четыре Animator’a:
1. двигает вниз footer списка;
2. двигает вниз кнопки.
3. скроллит ScrollView до самого низа;
4. накладывает alpha эффект на recyclerView.
Пишем игру для Android. Часть 4 – Спрайтовая анимация
На прошлых уроках мы говорили о работе с графикой. Мы вывели на экран изображение робота и заставили его двигаться. Однако пока наша поделка выглядит довольно тускло. Чтобы вдохнуть в наш объект жизнь, необходимо добавить анимацию, заставить поднимать ноги и дрыгать ручками в процессе перемещения по экрану.
Давайте на какое-то время отвлечемся от игры и поговорим об анимации вообще. Представим, что нам требуется нарисовать человечка, который шагает слева направо по экрану. Как это можно реализовать? Обычно новичкам эта задача кажется непомерно трудной. На самом деле здесь нет ничего сложного. Идея взята из кинематографа. У нас должен быть набор изображений, представляющий собой “фотографии” нашего человечка в разные, достаточно близкие, моменты времени. Быстро меняя кадры, мы увидим, что наша картинка начала двигаться. Ситуацию с походкой упрощает тот факт, что она носит периодический характер. Грубо говоря, чтобы получить красивую и достоверную анимацию нам достаточно иметь кадры с момента, когда человечек опирается, скажем, на левую ногу, до момента, когда он сделав два шага вновь на нее обопрется.
Давайте рассмотрим пример, состоящий из нескольких кадров. Не будем заморачиваться на графике и возьмем готовый рисунок из некогда популярной компьютерной игры Monkey Island.
В компьютерной графике и gamedev-е широко используется понятиеспрайт(sprite). В современной трактовке оно означает графический объект, который может перемешаться по экрану и при этом изменять свой вид. Со спрайтом связан рисунок, содержащий раскадровку и, в зависимости от ситуации, спрайт имеет вид того или иного кадра. Ниже приведет пример рисунка с последовательностью кадров, который будет использоваться нами для создания спрайта.
Это изображение имеет ширину в 150 точек, и содержит 5 кадров, то есть ширина каждого кадра составляет 30 пикселей.
Чтобы создать анимацию мы можем загрузить каждый кадр, как отдельную картинку и затем через равные интервалы времени выводить их последовательно на экран. Можно сделать по-другому: загрузить одну картинку, содержащую все кадры, а затем налету разбивать ее на кадры и выводить требуемый в данный момент кадр. На самом деле это довольно просто. Мы знаем, что наша картинка содержит 5 кадров шириной 30 пикселей. Определим прямоугольник, имеющий ширину кадра (30 точек) и высоту всего изображения. На приведенном ниже рисунке синими прямоугольниками отмечены первые два кадра.
Давайте продолжим разработку нашей игры. Создадим проект. За основу возьмем разработанный на предыдущих уроках пример Droid_03. Добавим в папку res/drawable-mdpi проекта файлwalk_elaine.png Создадим новый класс для нашего персонажа. Поскольку в Monkey Island персонаж зовут Elaine, назовем класс ElaineAnimated.
Здесь bitmap – png рисунок, содержащий все кадры; sourceRect – прямоугольная область, которая “очерчивает” в рисунке границы текущего кадра; frameTicker – переменная, содержащая время, которое прошло с момента последной смены кадра анимации. Указанная в комментарии переменная fps обозначает не fps игры, а fps спрайта, то есть сколько раз изменяется кадр спрайта за секунду. Для плавной анимации это значение должно иметь величину порядка 25-30, однако для наших учебных целей подойдет и более скромное число 5. Мы не можем поставить здесь большее значение, поскольку у нас всего 5 кадров в рисунке. framePeriod – период между сменой кадра в миллисекундах. Для нашего случая, когда мы хотим менять 5 кадров в секунду эта величина равна 200 мс.
Подразумевается, что кадры имеют одинаковую ширину, поэтому spriteWidth вычисляется, как общая ширина рисунков поделенная на число кадров. В конструктор передается параметр fps, который обозначает число кадров спрайта в секунду.
Добавим в конструктор класса MainGamePanel строку, создающую объект для нашего нового анимированного персонажа
Добавим в класс метод update, который будет изменять текущий кадр в зависимости от текущего времени. Мы специально не привязываемся к частоте обновления игрового цикла, чтобы не нарушать процессор лишней работой. Например, допустим, что наша программа запущена на очень продвинутом телефоне, который обеспечивает проход итерации игрового цикла за 20 мс, допустим также, что менять картинку спрайта нужно раз в 200 мс, таким образом, мы должны обновлять спрайт каждый десятый шаг игрового цикла.
Этот метод получает в качестве параметра текущее время и если это время превышает сумму времени последнего обновления (frameTicker) и длительности показа кадра (framePeriod), то необходимо перейти к показу следующего кадра. Для этого увеличиваем на единицу значение переменная currentFrame, а затем на основании ее значения вычисляем заново границы кадра (sourceRect.left и sourceRect.right).
Внесем изменение в метод update класса MainGamePanel
Теперь у нашего спрайта меняются кадры, но мы не видим этого. Добавим в класс ElaineAnimated метод draw, который будет выводить на экран текущий кадр
Команда canvas.drawBitmap рисует прямоугольную область sourceRect из рисунка bitmap в прямоугольной области destRect.
Изменим также метод onDraw, добавив туда вызов метода перерисовки спрайта
Вообще на этом можно было бы остановиться. Все работает, картинки меняются, человечек дрыгает ножками и машет ручками, но чтобы окончательно разобраться в том, как собственно происходит смена кадров, давайте чуть-чуть модифицируем метод draw. Нарисуем ниже анимированного спрайта всю картинку bitmap и будем поверх нее выводить прозрачный зеленый квадратик, соответствующий текущему слайду. Практической пользы в этом, конечно, нет, но для общего понимания идеологии работы со спрайтами весьма полезно