AndEngine. Первый опыт

21 апреля 2011 г.

Краткое вступление

В ноябре прошлого года, я приобрел свой первый смартфон на ОС Android. Это был великолепный HTC Desire! Наигравшись с аппаратом вдоволь, я начал изучать его с профессиональной точки зрения, а именно, с точки зрения программирования. Прочитав различные статьи, установил весь необходимый инструментарий для разработки. И тут встал вопрос, что же мне такое написать? Ответ не заставил себя долго ждать, хочу написать игру! Простую, не затейливую, красивую и интересную игру.

Первое, что мне необходимо было сделать — это определиться с тем, каким образом я буду выводить графическую информацию на экран. Начал с изучения OpenGl ES, прочитал много статей, изучил материалы уроков по выводу графики и понял, что я хочу писать игру, а не придумывать очередные велосипеды. Выход один — найти графический движок. Я нашел AndEngine!

Знакомство с этим великолепным движком я начал с загрузки приложения, демонстрирующего возможности AndEngine. Изучение исходных кодов внушило оптимизм, даже не смотря на отсутствие нормальной документации. Этот пробел успешно заполняет форум разработчиков и раздел с исходниками.

Самое главное — это начать, поэтому я попробую подробно описать процесс создания первого приложения, с использованием графического движка AndEngine.

Необходимые инструменты и файлы

  • Установленный и настроенный инструментарий для разработки приложений под Android(я использую среду разработки Eclipse).
  • Библиотечный файл andengine.jar
  • Ну и желание, без него никуда.

Создание проекта

Первым делом, создаем стандартный проект для Android приложения. Назовем его AndEngineHello. Движок AndEngine прекрасно работает с версией Android 1.6, поэтому при создании проекта выбираем именно этот пункт.

После нажатия кнопки “Finish” у нас сгенерирован вполне стандартный проект. Далее создадим в корне новый каталог с именем lib. И скопируем в этот каталог, заранее скаченный файл andengine.jar(я просто перетащил из проводника Windows файл в папку lib).

Затем, нажатием правой кнопки мыши на andengine.jar вызываем меню и выбираем пункт «Build Path» -> «Add To Build Path», тем самым добавляя библиотеку в проект. С настройками пока закончим и перейдем непосредственно к коду. Откроем наш главный класс AndEngineHello.

package com.andenginehello;
import android.app.Activity;
import android.os.Bundle;
public class AndEngineHello extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Удалим функцию OnCreate, а класс Activity заменим на BaseGameActivity из библиотеки AndEngine. BaseGameActivity — это основной класс графического приложения, наследуемый от Activity. Теперь нам нужно переопределить следующие 4 функции этого класса.

  • Engine onLoadEngine() — в этой функции будем создавать объект Engine, это и есть основной класс движка.
  • void onLoadResources() — в этой функции мы загружаем необходимые нам ресурсы, такие как шрифты, текстуры и т.п.
  • Scene onLoadScene() — здесь мы создаем объект Scene, отвечающий за отображение графических объектов, таких как спрайты, линии, прямоугольники и т.п.
  • void onLoadComplete() — эта функция выполняется самой последней, в ней можно выполнить какие то обобщающие действия.

После всех изменений, исходный код класса AndEngineHello будет выглядеть так:

package com.andenginehello;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.ui.activity.BaseGameActivity;
public class AndEngineHello extends BaseGameActivity {
@Override
public Engine onLoadEngine() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onLoadResources() {
// TODO Auto-generated method stub
}
@Override
public Scene onLoadScene() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
}

Для начала нам нужно определить с каким разрешением экрана мы будем работать, для моего Дезайра подходит 480×800. Определим следующие переменные:

// размеры окна отображения
public static final int CAMERA_WIDTH = 800;
public static final int CAMERA_HEIGHT = 480;
// класс Camera определяет текущую область видимости на экране
private Camera mCamera;

Следующим шагом, напишем код наших функций. Начнем с onLoadEngine():

@Override
public Engine onLoadEngine() {
//Создадим новый объект камеры, с размерами нашего экрана.
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
//Класс RatioResolutionPolicy отвечает за пропорции ширины и высоты экрана.
//Чтобы пропорции соответствовали нашему экрану, в качестве параметров введем размеры экрана.
RatioResolutionPolicy Resolution = new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT);
//Класс EngineOptions является хранилищем настроек для основного класса движка Engine.
//Первый параметр равен конструктора pFullscreen = true,
//выставляем таким образом полноэкранный режим.
//Второй параметр - ориентация экрана, будем использовать ландшафный режим.
//Третий параметр - пропорции экрана, мы его инициализировали выше.
//Последний четвертый параметр - наша камера.
EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE, Resolution, this.mCamera);
//в результате, нам необходимо вернуть объект класса Engine,
//параметром конструктора класса являются настройки.
return new Engine(engineOptions);
}

Теперь изменим функцию Scene onLoadScene():

@Override
public Scene onLoadScene() {
//Создаем объект класса Scene. Это и есть наш хранитель всей отображаемой графической информации,
//такой как спарйты, шрифты, линии, прямоугольники и т.п.
Scene scene = new Scene(1);
return scene;
}

В принципе, наш проект готов для первого запуска. Скомпилируем и запустим его. Если, после запуска, мы увидим чистый черный экран, то у нас все получилось, движок и сцена инициализированы и готовы к работе.

А теперь в качестве примера, давайте выведем на экран анимированное изображение. Для этого нам понадобиться графический файл, например вот этот:

Первым делом, создадим в нашем проекте подкаталог с именем gfx в каталоге asset, и поместим туда наш файл с именем funny_face.png. Размеры нашей картинки 512 в высоту, на 512 в ширину, она содержит 4 кадра, таким образом размер каждого 256×256. Теперь нужно загрузить этот файл как текстуру в память. Создадим в нашем классе следующие переменные:

//Хранение текстуры в памяти.
private Texture mTexture;
//Координаты нужной части текстуры для анимированного спрайта
private TiledTextureRegionmTextureRegion;
//Анимированный спрайт
private AnimatedSprite mAnimatedSprite;

Затем отредактируем функцию void onLoadResources():

@Override
public void onLoadResources() {
//Создаем текстуру размерами 512x512.
//Обратите внимание, каждый размер текстуры должен равняться значению 2 в n-ой степени!
this.mTexture = new Texture(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
//Установим путь по умолчанию для файлов
TextureRegionFactory.setAssetBasePath("gfx/");
//Загружаем графические данные из файла.
//Первый параметр - наша текстура.
//Второй - текущий контекст, ресурсы из нашего приложения.
//Третий параметр имя файла.
//Четвертый и пятый - начальные координаты хранения графики в текстуре.
//Шестой и седьмой - количество кадров по горизонтали и вертикали соответственно.
this.mTextureRegion = TextureRegionFactory.createTiledFromAsset( this.mTexture, this, "funny_face.png", 0, 0, 2, 2);
//Загружаем текстуру
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
Теперь создадим спрайт и поместим его на сцену. Редактируем функцию <b>onLoadScene()</b>:
@Override
public Scene onLoadScene() {
//Создаем объект класса Scene. Это и есть наш хранитель всей отображаемой графической информации,
//такой как спарйты, шрифты, линии, прямоугольники и т.п.
Scene scene = new Scene(1);
// создаем новый анимированный спрайт, задаем его начальную координату(300, 100).
this.mAnimatedSprite = new AnimatedSprite(300, 100, this.mTextureRegion );
//Включаем простую последовательную анимацию с частотой 100 мсек.
this.mAnimatedSprite.animate(100);
//Добавляем спрайт на сцену
scene.getLastChild().attachChild(this.mAnimatedSprite);
return scene;
}

Вот и все. Запускаем проект! Если мы сделали все правильно, то на экране увидим спрайт, машущий нам рукой.

Я надеюсь, что эта статья окажется полезной для тех людей, кто хочет начать писать игры или графические приложения, но не знает с чего начать.

Полезные ссылки

  1. Официальный сайт
  2. Форум разработчиков;
  3. Исходный код и примеры использования
Теги: рубрика Интернет