2D анимация – техника, используемая для создания иллюзии движения, используя статические изображения. Данная статья описывает, как создать анимацию в libGDX приложении.
Детали
Анимация состоит из множества кадров, которые показываются в последовательности через определенные интервалы времени. Анимацию бегущего человека можно достигнуть путем использования изображений, во время бега, и бесконечным проигрыванием этих изображений в обратном порядке.
Следующее изображение показывает полный цикл бега. Такое изображение называется спрайт-листом. Каждая область является спрайтом и называется кадром. Для создания анимации бега, спрайты должны быть нарисованы один за другим, по истечению определенного времени.
В зависимости от того, как быстро бежит персонаж, нужно определить, сколько времени кадр будет оставаться на экране. Кадровая частота – количество сменяемых кадров за секунду. Посмотрев на спрайт-лист, мы увидим полный цикл бега, состоящий из 30 кадров. Если полный цикл бега персонажа укладывается в одну секунду, то мы должны показывать 30 кадров в секунду. Это дает нам кадровую частоту в 30 FPS (Frames Per Second). Двигаясь дальше, нетрудно рассчитать время состояния (время кадра), которое показывает, сколько времени кадр должен отображаться на экране перед тем, как его сменит следующий кадр. 1 секунда / 30 = 0,033.
Другими словами, чтобы анимация была в 30 FPS, кадр должен сменяться каждые 0.033 секунды.
Анимация является простым конечным автоматом. Так, бегущий человек имеет 30 состояний, согласно спрайт-листу. Пронумерованные кадры бегущего человека представляют состояния, через которые он проходит.
В любой момент времени, конечный автомат может находиться в двух или более состояниях. Когда персонаж находится в состоянии 1, то рисуется спрайт, связанный с этим состоянием. Персонаж находится в этом состоянии 0.033 секунды и как только это время проходит, он движется (переходит) в следующее состояние, которое равно 2. Это продолжается пока не будет достигнуто последнее состояние или кадр.
Циклическая анимация означает переход на начало, когда анимация достигает последнего кадра.
Использовать анимацию в libGDX чрезвычайно просто. Есть одно ограничение, касающееся размера спрайт-листа, которое нужно запомнить: когда используется OpenGL 1.x, размер спрайта должен быть степенью двойки.
Следующий фрагмент кода создает объект Animation
(код) класса, используя
animation_sheet.png спрайт-лист и визуализирует анимацию на экране. В данном случае ApplicationListener будет очень простым.
public class Animator implements ApplicationListener {
private static final int FRAME_COLS = 6; // #1
private static final int FRAME_ROWS = 5; // #2
Animation walkAnimation; // #3
Texture walkSheet; // #4
TextureRegion[] walkFrames; // #5
SpriteBatch spriteBatch; // #6
TextureRegion currentFrame; // #7
float stateTime; // #8
@Override
public void create() {
walkSheet = new Texture(Gdx.files.internal("animation_sheet.png")); // #9
TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth()/FRAME_COLS, walkSheet.getHeight()/FRAME_ROWS); // #10
walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS];
int index = 0;
for (int i = 0; i < FRAME_ROWS; i++) {
for (int j = 0; j < FRAME_COLS; j++) {
walkFrames[index++] = tmp[i][j];
}
}
walkAnimation = new Animation(0.025f, walkFrames); // #11
spriteBatch = new SpriteBatch(); // #12
stateTime = 0f; // #13
}
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // #14
stateTime += Gdx.graphics.getDeltaTime(); // #15
currentFrame = walkAnimation.getKeyFrame(stateTime, true); // #16
spriteBatch.begin();
spriteBatch.draw(currentFrame, 50, 50); // #17
spriteBatch.end();
}
}
Настройка
# 1 и # 2 определяют константы, представляющие, сколько спрайтов будет расположено по вертикали и горизонтали в спрайт-листе.
Спрайт-лист содержит кадры одинакового размера, и все они выровнены.
#3 – объявление walkAnimation объекта, который является реализацией libGDX анимации.
#4 – Текстура, которая будет содержать весь лист в виде одного изображения (текстуры).
#5 – Объявление walkFrames как массива объектов TextureRegion. Массив будет содержать каждый кадр (спрайт) анимации. Первый элемент содержит верхний
левый кадр, второй элемент содержит следующий справа кард и так далее. При достижении последнего элемента ряда, следующий ряд начинается с самого левого
элемента.
#6 – SpriteBatch используется для рисования текстуры на экране.
#7 – Переменная currentFrame будет содержать текущий кадр и представляет собой регион, который рисуется при каждом вызове визуализации.
#8 – stateTime представляет количество секунд, прошедших с начала анимации. Используется для определения состояния анимации. Представляет простой аккумулятор, на
основе которого анимация знает, когда перейти к следующему состоянию.
Например, если анимация 30 FPS, то изменение состояния должно происходить каждые 33,3 миллисекунды. Если обновление происходит каждые 10 миллисекунд, то
stateTime содержит прошедшее время с начала анимации и переход анимации к следующему состоянию (кадру) будет на четвертом обновлении.
#9 – Создает текстуру из animation_sheet.png файла, находящегося в assets директории проекта (смотрите настройку проекта).
#10 и #11 – Используя TextureRegion.split() метод и текстуру, получаем двумерный массив кадров из текстуры. Имейте в виду, что это работает
только, если кадры имеют одинаковый размер. С помощью временной переменной tmp происходит наполнение walkFrames массива. Это необходимо, так как
анимация работает только с одномерными массивами.
#12 – инициализирует SpriteBatch, который будет рисовать кадр.
#12 – Сбрасывает stateTime в ноль. Переменная stateTime начнет накапливать время при каждом вызове визуализации.
Метод визуализации
#14 – Очищает экран при каждом кадре.
#15 – Добавляет время в stateTime, прошедшее с момента последней визуализации.
#16 – Получает текущий кадр, основываясь на текущем времени анимации. Вторая переменная для цикличности. Передавая true, мы говорим
анимации о возобновлении после достижения последнего кадра.
#17 – Визуализирует текущий кадр на экране, используя SpriteBatch на 50,50.
Запуск вышеуказанного фрагмента кода покажет хорошую гладкую анимацию бега человека.
Создание анимации, используя следующий конструктор, очень простое.
| Метод и описание |
|---|
Animation(float frameDuration, TextureRegion... keyFrames)
Первым параметром является время кадра, а второй параметр представляет собой массив из регионов (кадров), составляющих анимацию. |
Лучшие практики
- Упаковка кадров в одну текстуру для оптимизации визуализации.
- Разумное число кадров в зависимости от типа игры. Для аркады в ретро стиле достаточно 4 кадров, в тоже время для более реалистичного движения требуется больше кадров.
Комментариев нет:
Отправить комментарий