Зимой прошлого года (скорее всего в солнечный день:) я заинтересовался графической библиотекой AndEngine, так как захотелось поработать с двумерной графикой на мобильном телефоне (с использованием OpenGL), и это решение мне показалось наиболее интересным и доступным. Сделав несколько графических приложений, я решил создать живые обои, тем более что в поставке с AndEngine идёт специальная библиотека для создания таковых. Теперь поделюсь своим опытом создания живых обоев с вами.
Специально для этого я подготовил проект (обладает обильными комментариями), «шаблон» для показа принципа работы живых обоев.

Подготовка
Прежде всего необходимо установить сам AndEngine и в частности библиотеку AndEngineLiveWallpaperExtension (рекомендую сразу установить все доступные библиотеки) так как она будет являться базой. Так как эта статья не является базовой для изучения AndEngine я не буду рассказывать как установить библиотеки, тем более что данную информацию вы можете легко найти, например здесь — http://www.matim-dev.com/how-to-setup-andengine.html. Теперь вам необходимо открыть прилагаемый проект и запустить его. Если он сразу не запустится, то скорее всего вам необходимо проверить подключенные библиотеки к проекту. В итоге у вас должно получиться что то типа этого — http://youtu.be/HRKzBma9vz0
Функционал
А теперь кратко и по порядку (большая часть функционал также относится ко всем другим AndEngine GLES2 приложениям). Предком главного класса проекта является «BaseLiveWallpaperService», именно этот класс отвечает за всю работу с GLES2. Обязательными для переопределения являются функции:
public void onSurfaceChanged(final GLState pGLState, final int pWidth, final int pHeight) — функция определения размера экрана и установки камеры.
public EngineOptions onCreateEngineOptions() — функция настройки работы движка живых обоев. Данная функция возвращает в систему выбранные параметры для настройки GLES2.
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) — как понятно из названия, данная функция предназначена для создания всех (медиа) ресурсов которые будут участвовать в работе приложения.
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) — функция создания сцены и размещения на ней всех желаемых объектов.
Загрузка тестур
Загрузка текстуры происходит в три этапа: определение атласа; определение текстуры; загрузка текстуры в атлас. Рассмотрим их на примере загрузки заднего фона:
В первой строке определяется размер для атласа текстур. Нужно заранее определить какие текстуры и в каком порядке расположатся на данном атласе и рассчитать его размер. Если неправильно рассчитать положение текстур в атласе или сделать его меньше требуемого размера, то програ��ма будет работать не корректно. В нашем случае в атласе будет располагаться всего одна картинка (спрайт) и поэтому размер атласа будет ровняться размеру картинки.
В случае если требуется загрузить две картинки (спрайта) и более, то размер атласа придётся высчитывать. Например: Мы хотим загрузить две картинки размером 60*60 и 80*75 пикселей. Для нахождения ширины атласа сложим ширину первой и второй картинки, получим 140. При этом высота атласа должна ровняться наибольшей из этих картинок. При необходимости компоновка атласа может быть любой сложности, всё ограничивается только фантазией программиста и максимальными размерами (2048*2048).

Во второй строке определяется объект через который в дальнейшем можно получить интересующую текстуру. Аргументы конструктора следующие: атлас для хранения текстуры; контекст; адрес расположения текстуры; координата по Х, начиная с которой располагается текстура; координата по Y, начиная с которой располагается текстура. Все текстуры должны храниться в парке «gfx» (проект/assets/gfx).
В третьей строке находится сам загрузчик, с помощью которого загружается вся графика в атлас.
Создание сцены
Сцена создается всего одной строкой — mScene= new Scene(), далее происходит самое интересное — размещение всех нужных объектов на сцене. Главной строительной единицей всех приложений строящихся с помощью AndEngine, являются спрайты (так как библиотека работает исключительно с двумерными объектами). Рассмотрим пример создания простого спрайта:
В первой строке создаётся спрайт. У конструктора следующие аргументы: положение на сцене по оси Х; положение на сцене по оси Y; объект текстуры; менеджер буфера. Во второй строке переопределяется размер спрайта, по умолчанию он равен размеру текстуры. В третьей строке переопределяется позиция спрайта на экране. В четвертой строке спрайт непосредственно добавляется на экран.
Если вы посмотрите код прилагаемого примера, то заметите что в нем определен класс Sun. Он является потомком класса Sprite. В этом классе прописана логика анимации объекта, которая заключается в повороте объекта относительно своего центра.
Также определен класс LiveWallpapperSettings, который отвечает за на��тройку живых обоев. Так как это достаточно стандартная вещь, логику работы настроек описывать не буду (интересующую информацию вы легко найдете в Яндексе либо в других поисковых машинах).
Заключение
Библиотека очень проста в использовании и функциональна. Главным её недостатком является механизм замораживания, который срабатывает при скрытии обоев и не всегда отключается при продолжении их показа. Данный минус явно прослеживается когда обои имеют относительно большое количество спрайтов на сцене (как например здесь — https://play.google.com/store/apps/details?id=com.livewallpaper.summermeado_wfull). Если кто-то решил проблему с замораживанием, пожалуйста поделитесь решением.
Я намеренно не стал раздувать пример и добавлять максимальное количество функционала чтобы показать, что графические приложения для Android это быстро и просто.
Удачного тестирования!
Проект живых обоев — http://www.anprog.com/documents/AE_gles2_LiveWallpaper.zip
Специально для этого я подготовил проект (обладает обильными комментариями), «шаблон» для показа принципа работы живых обоев.

Подготовка
Прежде всего необходимо установить сам AndEngine и в частности библиотеку AndEngineLiveWallpaperExtension (рекомендую сразу установить все доступные библиотеки) так как она будет являться базой. Так как эта статья не является базовой для изучения AndEngine я не буду рассказывать как установить библиотеки, тем более что данную информацию вы можете легко найти, например здесь — http://www.matim-dev.com/how-to-setup-andengine.html. Теперь вам необходимо открыть прилагаемый проект и запустить его. Если он сразу не запустится, то скорее всего вам необходимо проверить подключенные библиотеки к проекту. В итоге у вас должно получиться что то типа этого — http://youtu.be/HRKzBma9vz0
Функционал
А теперь кратко и по порядку (большая часть функционал также относится ко всем другим AndEngine GLES2 приложениям). Предком главного класса проекта является «BaseLiveWallpaperService», именно этот класс отвечает за всю работу с GLES2. Обязательными для переопределения являются функции:
onSurfaceChanged
onCreateEngineOptions
onCreateResources
onCreateScene
public void onSurfaceChanged(final GLState pGLState, final int pWidth, final int pHeight) — функция определения размера экрана и установки камеры.
public EngineOptions onCreateEngineOptions() — функция настройки работы движка живых обоев. Данная функция возвращает в систему выбранные параметры для настройки GLES2.
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) — как понятно из названия, данная функция предназначена для создания всех (медиа) ресурсов которые будут участвовать в работе приложения.
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) — функция создания сцены и размещения на ней всех желаемых объектов.
Загрузка тестур
Загрузка текстуры происходит в три этапа: определение атласа; определение текстуры; загрузка текстуры в атлас. Рассмотрим их на примере загрузки заднего фона:
this.mOnScreenControlTexture0 = new BitmapTextureAtlas(this.getTextureManager(), 1930, 1050, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.bg_TextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture0,this,"gfx/bg.jpg", 0, 0);
this.getEngine().getTextureManager().loadTexture(this.mOnScreenControlTexture0);
В первой строке определяется размер для атласа текстур. Нужно заранее определить какие текстуры и в каком порядке расположатся на данном атласе и рассчитать его размер. Если неправильно рассчитать положение текстур в атласе или сделать его меньше требуемого размера, то програ��ма будет работать не корректно. В нашем случае в атласе будет располагаться всего одна картинка (спрайт) и поэтому размер атласа будет ровняться размеру картинки.
В случае если требуется загрузить две картинки (спрайта) и более, то размер атласа придётся высчитывать. Например: Мы хотим загрузить две картинки размером 60*60 и 80*75 пикселей. Для нахождения ширины атласа сложим ширину первой и второй картинки, получим 140. При этом высота атласа должна ровняться наибольшей из этих картинок. При необходимости компоновка атласа может быть любой сложности, всё ограничивается только фантазией программиста и максимальными размерами (2048*2048).

Во второй строке определяется объект через который в дальнейшем можно получить интересующую текстуру. Аргументы конструктора следующие: атлас для хранения текстуры; контекст; адрес расположения текстуры; координата по Х, начиная с которой располагается текстура; координата по Y, начиная с которой располагается текстура. Все текстуры должны храниться в парке «gfx» (проект/assets/gfx).
В третьей строке находится сам загрузчик, с помощью которого загружается вся графика в атлас.
Создание сцены
Сцена создается всего одной строкой — mScene= new Scene(), далее происходит самое интересное — размещение всех нужных объектов на сцене. Главной строительной единицей всех приложений строящихся с помощью AndEngine, являются спрайты (так как библиотека работает исключительно с двумерными объектами). Рассмотрим пример создания простого спрайта:
bg = new Sprite(0, 0, this.bg_TextureRegion, getVertexBufferObjectManager());
bg.setSize(bg.getWidth() * 2, bg.getHeight() * 2);
bg.setPosition(10, 20);
mScene.attachChild(bg);
В первой строке создаётся спрайт. У конструктора следующие аргументы: положение на сцене по оси Х; положение на сцене по оси Y; объект текстуры; менеджер буфера. Во второй строке переопределяется размер спрайта, по умолчанию он равен размеру текстуры. В третьей строке переопределяется позиция спрайта на экране. В четвертой строке спрайт непосредственно добавляется на экран.
Если вы посмотрите код прилагаемого примера, то заметите что в нем определен класс Sun. Он является потомком класса Sprite. В этом классе прописана логика анимации объекта, которая заключается в повороте объекта относительно своего центра.
Также определен класс LiveWallpapperSettings, который отвечает за на��тройку живых обоев. Так как это достаточно стандартная вещь, логику работы настроек описывать не буду (интересующую информацию вы легко найдете в Яндексе либо в других поисковых машинах).
Заключение
Библиотека очень проста в использовании и функциональна. Главным её недостатком является механизм замораживания, который срабатывает при скрытии обоев и не всегда отключается при продолжении их показа. Данный минус явно прослеживается когда обои имеют относительно большое количество спрайтов на сцене (как например здесь — https://play.google.com/store/apps/details?id=com.livewallpaper.summermeado_wfull). Если кто-то решил проблему с замораживанием, пожалуйста поделитесь решением.
Я намеренно не стал раздувать пример и добавлять максимальное количество функционала чтобы показать, что графические приложения для Android это быстро и просто.
Удачного тестирования!
Проект живых обоев — http://www.anprog.com/documents/AE_gles2_LiveWallpaper.zip