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 кадров, в тоже время для более реалистичного движения требуется больше кадров.
Комментариев нет:
Отправить комментарий